Showing posts with label Bash. Show all posts
Showing posts with label Bash. Show all posts

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.

Tuesday, 25 June 2024

jq -r bash cmd

https://www.baeldung.com/linux/jq-command-json 

The command jq -r 'select(.Update) | .Path + "@" + .Update.Version' is used within a shell script to filter and format JSON output from the go list -u -m -json all command. Here’s a detailed breakdown of what each part of the command does:

Explanation of the Command

jq -r

  • jq: A lightweight and flexible command-line JSON processor. It allows you to parse, filter, and manipulate JSON data.
  • -r: This option stands for "raw output." It outputs the filtered and transformed results as plain text instead of JSON, which is often easier to use in shell scripts.

'select(.Update)'

  • select(.Update): This is a filter expression that selects only those JSON objects where the .Update field exists and is not null.
    • select: A jq function that filters JSON objects based on a condition.
    • .Update: A field in the JSON object output by go list -u -m -json all. This field contains update information for each Go module if an update is available.

'| .Path + "@" + .Update.Version'

  • |: A pipe operator that passes the filtered results from the left side (select(.Update)) to the right side.
  • .Path: This represents the Path field in the JSON object, which contains the module path (e.g., github.com/pkg/errors).
  • + "@": This concatenates the module path with the "@" symbol, used to specify a version in Go modules.
  • .Update.Version: This accesses the Version field within the Update object, which specifies the new version available for the module.

Combined Effect

The command as a whole does the following:

  1. Filter Modules with Updates: select(.Update) filters out all the modules that do not have an available update. Only the modules with the .Update field present are passed to the next step.
  2. Format Output: For each filtered module, the output is formatted as <module-path>@<new-version>. For example, if the module github.com/pkg/errors has an update to version v0.9.2, it outputs github.com/pkg/errors@v0.9.2.

Example

Assume you have a JSON output from go list -u -m -json all like this:

json
[ { "Path": "github.com/pkg/errors", "Version": "v0.9.1", "Update": { "Version": "v0.9.2" } }, { "Path": "golang.org/x/sys", "Version": "v0.0.0-20220315054443-0e35b0f21f97", "Update": { "Version": "v0.0.0-20220315190503-a33c662eeddc" } } ]

Running the jq command would filter and format it like this:

sh
github.com/pkg/errors@v0.9.2 golang.org/x/sys@v0.0.0-20220315190503-a33c662eeddc

This output is plain text and can be easily used in subsequent commands, such as go get, to update each module.

Usage in Shell Scripts

In a shell script, this output can be looped over to update all the dependencies that have updates available:

sh
modules=$(go list -u -m -json all | jq -r 'select(.Update) | .Path + "@" + .Update.Version') for module in $modules; do echo "Updating $module" go get $module done go mod tidy
  • modules=$(...): Executes the command within $(...) and stores the result in the modules variable.
  • for module in $modules; do ... done: Iterates over each module and runs go get to update it.

This approach ensures that only the modules with available updates are processed and updated efficiently.

Wednesday, 24 January 2024

bash script positional arguments

https://hbctraining.github.io/Training-modules/Intermediate_shell/lessons/positional_params.html 

Here we can see that our command is the first positional parameter ($0) and that each of the strings afterwards are additional positional parameters (here $1 and $2). Generally when we refer to positional parameters we ignore $0 and start with $1.

It is crucial to note that different positional parameters are separated by whitespace and can be strings of any length. This means that:

$ ./myscript.sh OneTwoThree

has only given one positional parameter $1=OneTwoThree

and

$ ./myscript.sh O N E

has given three positional parameters $1=O $2=N $3=E