{
  "slug": "shell-script-linter",
  "name": "gizza-ai/shell-script-linter",
  "version": "0.1.0",
  "title": "Shell Script Linter — Bash and sh Pitfall Checker — gizza.ai",
  "description": "Paste a bash, sh, dash or zsh script and catch common shell pitfalls: unquoted variables, missing strict mode, useless cat, risky rm -rf and subshell scope traps.",
  "tags": [
    "shell script",
    "bash",
    "sh",
    "linter",
    "shellcheck",
    "strict mode",
    "ci",
    "scripting"
  ],
  "category": "developer",
  "urls": {
    "page": "https://gizza.ai/tools/shell-script-linter/",
    "markdown": "https://gizza.ai/tools/shell-script-linter/index.md",
    "descriptor": "https://gizza.ai/tools/shell-script-linter/tool.json",
    "deep_link_example": "https://gizza.ai/tools/shell-script-linter/?script=%23%21%2Fusr%2Fbin%2Fenv%20bash%0Afor%20f%20in%20%24%28ls%20%2A.txt%29%3B%20do%0A%20%20cat%20%24f%20%7C%20while%20read%20line%3B%20do%0A%20%20%20%20echo%20%24line%0A%20%20done%0Adone&shell=auto&min_severity=all&ignore=LEGACY-TEST%2C%20USELESS-CAT&format=text"
  },
  "cli": "gizza tool shell-script-linter '#!/usr/bin/env bash\nfor f in $(ls *.txt); do\n  cat $f | while read line; do\n    echo $line\n  done\ndone'",
  "tool": {
    "description": "Lint a pasted bash/sh script without running it. Reports block-structure errors (unclosed if/do/case, unterminated quotes) plus common pitfalls: unquoted expansions that word-split, useless use of cat, legacy backticks, missing set -e/-u/-o pipefail, pipe-to-while subshell scope loss, unguarded cd, parsing ls output, spaced assignments, single-bracket tests, risky rm -rf on an interpolated path, and bashisms under a POSIX sh shebang. Parameters: script text, shell (auto/bash/sh/dash/zsh), min_severity filter, ignore list of rule codes, and text/json output.",
    "parameters": {
      "additionalProperties": false,
      "properties": {
        "format": {
          "default": "text",
          "description": "Output format. 'text' is a human-readable report with line numbers, severities and the offending source line; 'json' returns the resolved shell, summary counts and a findings array for CI.",
          "enum": [
            "text",
            "json"
          ],
          "type": "string"
        },
        "ignore": {
          "default": "",
          "description": "Optional comma- or space-separated rule codes to suppress, e.g. 'LEGACY-TEST, USELESS-CAT'. Valid codes: SYNTAX, MISSING-SHEBANG, STRICT-MODE, UNQUOTED-VAR, USELESS-CAT, BACKTICKS, SUBSHELL-SCOPE, UNCHECKED-CD, PARSE-LS, ASSIGN-SPACES, LEGACY-TEST, RM-RISK, SH-BASHISM.",
          "type": "string"
        },
        "min_severity": {
          "default": "all",
          "description": "Minimum severity to report. 'all' includes info-level style hints, 'warning' hides them, 'error' shows only structural problems such as unclosed blocks, spaced assignments and risky rm -rf.",
          "enum": [
            "all",
            "warning",
            "error"
          ],
          "type": "string"
        },
        "script": {
          "description": "Shell script text to lint, up to 200000 bytes. Comments, single-quoted strings and here-doc bodies are masked first, so examples inside a comment do not produce findings. The script is never executed.",
          "type": "string"
        },
        "shell": {
          "default": "auto",
          "description": "Which shell to lint for. 'auto' reads the shebang and falls back to bash. 'sh' and 'dash' enable the SH-BASHISM rule and skip the bash-only LEGACY-TEST hint; 'bash' and 'zsh' do the opposite.",
          "enum": [
            "auto",
            "bash",
            "sh",
            "dash",
            "zsh"
          ],
          "type": "string"
        }
      },
      "required": [
        "script"
      ],
      "type": "object"
    }
  }
}