Thursday, 12 March 2026

Bash $?, and exit code

 Bash $?, exist code

every command executed by the shell ends with an exit code, not just Bash scripts.

Even though npm run lint is not a Bash script, it is still a process executed by the shell, and every process on Unix-like systems (Linux, macOS, etc.) returns an exit status when it finishes.

How the chain works

When you run:

npm run lint

this happens under the hood:

  1. Bash launches the program npm.

  2. npm reads package.json and finds the lint script.

  3. npm launches the command defined there (for example eslint .).

  4. That program finishes and returns an exit code.

  5. npm forwards that exit code back to the shell.

  6. Bash stores it in $?.

Example package.json:


In Bash, the key piece is this line:

STATUS=$?

$? is a special Bash variable that always contains the exit code of the last command that ran.

Step-by-step what happens

  1. Change directory:

cd cli
  1. Run the lint script:

npm run lint
  • This runs the lint script defined in your package.json.

  • When it finishes, it exits with a status code:

    • 0 → success

    • non-zero (e.g., 1) → failure

  1. Capture that exit code:

STATUS=$?
  • $? now holds the exit code returned by npm run lint.

  • That value gets stored in the variable STATUS.

  1. Check if it failed:

if [ $STATUS -ne 0 ]; then
  • -ne means not equal.

  • So if the exit code is not 0, the script treats it as a failure.

  1. Abort the commit:

echo "Lint failed. Commit aborted."
exit 1

Otherwise:

echo "Lint passed."
exit 0

Example

If your lint script is something like:

"scripts": {
"lint": "eslint ."
}
  • If eslint finds errors → exits 1$? becomes 1 → commit aborted.

  • If no errors → exits 0$? becomes 0 → commit continues.

Simpler equivalent

You can write the same logic more directly:

cd cli

if ! npm run lint; then
echo "Lint failed. Commit aborted."
exit 1
fi

echo "Lint passed."
exit 0

Here if ! command automatically checks the exit code.

No comments:

Post a Comment