Ravindra BagaleCourses & study guides मराठी Track your progress

Shell Scripting Complete 9: Arithmetic, Exit Codes, set -euo pipefail and Error Handling

A script that keeps going after a failure is dangerous: it may delete the wrong folder or upload half a backup. In this chapter you learn bash arithmetic with $(( )) and (( )), decimals with bc and awk, what exit codes are and how to read $? and PIPESTATUS, how && and || chain steps, the safe header set -euo pipefail and its traps, and clean error handling with a die function, return codes and retries. Every topic starts with an everyday example and then shows examples from many industries.

What you'll learn in this chapter

  • Do integer maths with $(( )) and (( ))
  • Do decimal maths with bc or awk
  • Read exit codes with $? and PIPESTATUS
  • Chain steps with && and ||
  • Use set -euo pipefail safely
  • Write die, retry and clean error messages

1. An everyday example: a pressure cooker whistle

Why do we need this?

In a Pune kitchen, the cooker whistle tells you what happened. Three whistles means done. No whistle means something is wrong and you check before serving. You would never serve dal without knowing it cooked. A command's exit code is that whistle: 0 means success, any other number means a problem, and a good script listens before moving to the next step.

What is it?

Whistle = exit code. Listening = checking $? or using if. Stopping the meal if something is wrong = set -e or || die. Counting whistles = arithmetic with (( )). Trying again after the gas went off = a retry loop.

How to do it (step by step)

How a safe script handles a stepRun the commandExit code 0? go onNot 0? print a clear error to stderrClean up temp filesExit with a non-zero codeCaller or cron sees the failure
Never hide a failure; make it loud.

2. Integer maths with $(( )) and (( ))

Why do we need this?

Counting files, adding totals, finding percentages for a disk alert: scripts do small maths all the time.

What is it?

$(( expr )) gives the result as text. (( expr )) runs the maths and its exit code is 0 if the result is not zero, so it works as a test. Inside, you do not need $ before names. Operators: + - * / % ** and comparisons < > == !=. Division is integer only: 7/2 is 3. let and expr are older ways; prefer (( )).

FormUse
$((a+b))result as text
((n++))increase n
((a>b))test, exit 0 if true
$((7%3))remainder 1
$((2**10))power 1024

How to do it (step by step)

  1. Add totals.
a=1200; b=850; echo $((a+b))

Output:

2050

What it means: No $ needed inside.

  1. Counter.
n=0; for f in *.log; do ((n++)); done; echo $n

Output:

3

What it means: Counts files.

  1. Percentage.
used=45; total=60; echo $((used*100/total))%

Output:

75%

What it means: Multiply first, then divide.

  1. Compare.
disk=91; (( disk > 85 )) && echo 'disk alert'

Output:

disk alert

What it means: (( )) as a test.

  1. Even or odd.
x=7; (( x % 2 == 0 )) && echo even || echo odd

Output:

odd

What it means: Remainder check.

3. Decimals with bc and awk

Why do we need this?

Prices with paise, GST at 18 percent, average response time in ms: bash alone cannot do decimals.

What is it?

bc is a calculator: echo 'scale=2; 10/3' | bc gives 3.33. scale sets decimal places. awk can also do it: awk 'BEGIN{printf "%.2f\n", 10/3}'. To compare decimals, let bc or awk return 1 or 0 and test that. Watch out: bc is not installed on some minimal images; awk almost always is.

How to do it (step by step)

  1. Divide with decimals.
echo 'scale=2; 10/3' | bc

Output:

3.33

What it means: scale=2.

  1. GST.
price=499.50; echo "scale=2; $price*1.18" | bc

Output:

589.41

What it means: 18 percent added.

  1. awk average.
printf '120\n95\n310\n' | awk '{s+=$1} END{printf "%.1f\n", s/NR}'

Output:

175.0

What it means: Average response ms.

  1. Compare decimals.
load=3.75; (( $(echo "$load > 2.5" | bc) )) && echo high

Output:

high

What it means: bc prints 1 for true.

4. Exit codes, $? and PIPESTATUS

Why do we need this?

Cron, CI systems and other scripts decide success or failure only from your exit code.

What is it?

Every command ends with a number from 0 to 255. 0 means success. 1 is a general error, 2 is misuse, 126 is not executable, 127 is command not found, 130 is stopped by Ctrl+C, 137 is killed (often out of memory). $? holds the last code; read it right away because the next command replaces it. In a pipe, $? is the last command's code; ${PIPESTATUS[@]} has all of them. exit N ends a script, return N ends a function.

CodeMeaning
0success
1general error
2bad usage
126not executable
127command not found
130Ctrl+C
137killed by signal 9

How to do it (step by step)

  1. Success code.
ls /etc/hostname; echo $?

Output:

/etc/hostname
0

What it means: 0 = OK.

  1. Failure code.
ls /nope; echo $?

Output:

ls: cannot access '/nope': No such file or directory
2

What it means: Not 0.

  1. Not found.
nosuchcmd; echo $?

Output:

bash: nosuchcmd: command not found
127

What it means: 127.

  1. Pipe codes.
false | true; echo "$? ${PIPESTATUS[@]}"

Output:

0 1 0

What it means: Last was true, first failed.

  1. Save it first.
grep -q ERROR app.log; rc=$?; echo "grep said $rc"

Output:

grep said 1

What it means: 1 means no match.

5. Chain steps with && and ||

Why do we need this?

Build then deploy only if the build worked; send an alert only if the check failed.

What is it?

a && b runs b only if a succeeded. a || b runs b only if a failed. if cmd; then ... fi tests a command's exit code directly, so you rarely need $?. ! cmd flips the result. Be careful with a && b || c: c also runs if b fails, so it is not a true if-else; use if for important logic.

How to do it (step by step)

  1. Only on success.
mkdir -p /tmp/rel && cd /tmp/rel && pwd

Output:

/tmp/rel

What it means: Stops at the first failure.

  1. Only on failure.
ping -c1 -W1 10.9.9.9 || echo 'gateway down'

Output:

gateway down

What it means: Alert path.

  1. if on a command.
if grep -q 'Out of memory' /var/log/syslog; then echo 'OOM seen'; fi

Output:

OOM seen

What it means: No $? needed.

  1. Negate.
if ! id deploy; then echo 'no deploy user'; fi

Output:

id: 'deploy': no such user
no deploy user

What it means: ! flips.

6. The safe header: set -euo pipefail

Why do we need this?

By default bash ignores failures and unset variables. One typo like rm -rf "$DIR/" with empty DIR can be a disaster.

What is it?

set -e exits when a command fails. set -u treats unset variables as errors. set -o pipefail makes a pipe fail if any part fails. Together: set -euo pipefail. Know the limits: -e does not fire inside if conditions, in parts of && or || lists, or for commands like ((n++)) when n was 0 (that returns 1 and kills the script). Use n=$((n+1)) or ((n++)) || true. grep with no match returns 1, so add || true when that is fine.

OptionEffect
-eexit on error
-uunset variable is error
-o pipefailpipe fails if any part fails
-xtrace each command

How to do it (step by step)

  1. Header.
#!/usr/bin/env bash
set -euo pipefail

What it means: First lines of a script.

  1. -u catches typos.
set -u; echo "$DIRR"

Output:

bash: DIRR: unbound variable

What it means: Stops before damage.

  1. pipefail.
set -o pipefail; false | sort; echo $?

Output:

1

What it means: Without it you get 0.

  1. Counter trap.
set -e; n=0; ((n++)); echo never

What it means: Script exits; use n=$((n+1)).

  1. Allowed failure.
count=$(grep -c WARN app.log || true); echo $count

Output:

0

What it means: No match is OK here.

7. Clear errors: stderr, die and usage

Why do we need this?

Error messages mixed into normal output break pipes and confuse the person on call at 3 a.m.

What is it?

Send errors to stderr with echo 'msg' >&2. Write a small die function that prints the message and exits with a code. Print a usage line and exit 2 when arguments are wrong. Include the script name with ${0##*/} and what failed, so the message is useful in logs.

How to do it (step by step)

  1. To stderr.
echo 'config missing' >&2

Output:

config missing

What it means: Not in stdout.

  1. die function.
die(){ echo "${0##*/}: $*" >&2; exit "${2:-1}"; }
[[ -r app.conf ]] || die 'cannot read app.conf'

Output:

backup.sh: cannot read app.conf

What it means: Clear and exits 1.

  1. Usage.
(( $# == 1 )) || { echo "usage: ${0##*/} ENV" >&2; exit 2; }

Output:

usage: deploy.sh ENV

What it means: Exit 2 = bad usage.

  1. Return from a function.
is_up(){ curl -fs -o /dev/null "$1"; }; is_up https://example.com && echo up

Output:

up

What it means: Function returns curl's code.

8. Retries and timeouts

Why do we need this?

Networks blink. A deploy should try a health check a few times before calling it a failure, and should not hang forever.

What is it?

A retry loop runs a command up to N times with a sleep between tries and returns failure at the end. Double the sleep each time (backoff) to be kind to a busy server. timeout 10 cmd kills cmd after 10 seconds and returns 124. Combine both for safe network steps.

How to do it (step by step)

  1. Retry function.
retry(){ local n=$1 d=1 i; shift; for ((i=1;i<=n;i++)); do "$@" && return 0; echo "try $i failed" >&2; sleep $d; d=$((d*2)); done; return 1; }

What it means: Backoff 1, 2, 4 seconds.

  1. Use it.
retry 3 curl -fsS http://localhost:8080/health

Output:

try 1 failed
OK

What it means: Second try worked.

  1. Timeout.
timeout 5 sleep 30; echo $?

Output:

124

What it means: 124 = timed out.

  1. Both.
retry 3 timeout 10 pg_isready -h db1 || die 'database not ready'

Output:

db1:5432 - accepting connections

What it means: Safe wait for a database.

9. Real examples from many industries

Why do we need this?

The same Linux skill shows up in every kind of company. Seeing it in many places helps you remember it.

What is it?

Each row is a made-up team. It shows who uses this and how.

How to do it (step by step)

Team and cityHow they use itCommand
Nikhil, logistics, PuneStop the route import if the CSV download failsset -euo pipefail
Grace, hospital, NairobiAlert when lab-results sync failsrsync -a src/ dst/ || alert
Hiro, manufacturing, OsakaAverage sensor temp with decimalsawk '{s+=$1} END{print s/NR}'
Olivia, retail, SydneyRetry the payment health checkretry 5 curl -fs "$URL"
Ahmed, telecom, DubaiDisk percent alert(( used*100/total > 90 ))
Sneha, edtech, BengaluruUsage error for bad argumentsexit 2

10. Common errors and how to fix them

Why do we need this?

Everyone hits these errors. Knowing the cause saves hours.

What is it?

Read the exact message first. Then match it to a row below.

How to do it (step by step)

Error you seeWhy it happensHow to fix
unbound variableset -u and var not setSet it or use a default.
echo "${VAR:-}"
Script exits silently after ((n++))n was 0, result 0, exit 1 under -eUse n=$((n+1)).
n=$((n+1))
value too great for baseLeading zero like 08 read as octalForce base 10.
echo $((10#08))
syntax error: invalid arithmetic operatorDecimal in $(( ))Use bc or awk.
echo '1.5+2' | bc
division by 0Divisor empty or zeroCheck before dividing.
(( total > 0 )) && echo $((u*100/total))
Pipe failure not detectedNo pipefailEnable it.
set -o pipefail
Script stops when grep finds nothinggrep returns 1 under -eAllow it.
grep x f || true
bc: command not foundMinimal imageInstall bc or use awk.
sudo dnf install -y bc
Exit code 141SIGPIPE: reader closed early with pipefailAvoid head on long pipes or ignore 141.
yes | head -1 || true

11. Troubleshooting step by step

Why do we need this?

When a script stops or does not stop, find which command returned what code.

What is it?

Go top to bottom. Stop at the first step that shows the problem.

How to do it (step by step)

  1. Print last code.
echo $?
  1. Pipe codes.
echo "${PIPESTATUS[@]}"
  1. Trace.
bash -x script.sh
  1. Show options.
echo $-; set -o | grep -E 'errexit|nounset|pipefail'
  1. Find the failing line.
trap 'echo "failed at line $LINENO" >&2' ERR
  1. Lint.
shellcheck script.sh

12. Lab 1: Disk usage alert with maths and exit codes

Why do we need this?

Write diskcheck.sh that reads disk use for / and exits 1 with a message when it is above a limit, so cron or a monitor can act on it.

What is it?

A full hands-on lab. Run every step on a test Linux machine (an EC2 instance, a VM, or WSL).

How to do it (step by step)

  1. Create script.
cat > ~/diskcheck.sh <<'X'
#!/usr/bin/env bash
set -euo pipefail
limit=${1:-85}
used=$(df --output=pcent / | tail -1 | tr -dc '0-9')
if (( used > limit )); then echo "disk / at ${used}% (limit ${limit}%)" >&2; exit 1; fi
echo "disk / ok at ${used}%"
X
chmod +x ~/diskcheck.sh
  1. Run.
~/diskcheck.sh; echo "rc=$?"

Output:

disk / ok at 41%
rc=0
  1. Low limit.
~/diskcheck.sh 10; echo "rc=$?"

Output:

disk / at 41% (limit 10%)
rc=1
  1. Use in a chain.
~/diskcheck.sh 10 || echo 'send alert now'

Output:

disk / at 41% (limit 10%)
send alert now
  1. Lint.
shellcheck ~/diskcheck.sh && echo clean

Output:

clean

13. Lab 2: See set -e and pipefail in action

Why do we need this?

Run the same small script with and without the safe header to see how it changes failures.

What is it?

A full hands-on lab. Run every step on a test Linux machine (an EC2 instance, a VM, or WSL).

How to do it (step by step)

  1. Unsafe script.
printf 'cat /nope | sort\necho "after: still running"\n' > ~/t.sh; bash ~/t.sh

Output:

cat: /nope: No such file or directory
after: still running
  1. Safe header.
sed -i '1i set -euo pipefail' ~/t.sh; bash ~/t.sh; echo "rc=$?"

Output:

cat: /nope: No such file or directory
rc=1
  1. Unset var.
bash -uc 'echo "$NOPE"'; echo "rc=$?"

Output:

bash: line 1: NOPE: unbound variable
rc=1
  1. Counter trap.
bash -ec 'n=0; ((n++)); echo reached'; echo "rc=$?"

Output:

rc=1
  1. Fixed counter.
bash -ec 'n=0; n=$((n+1)); echo reached $n'

Output:

reached 1
  1. Clean.
rm ~/t.sh

Ravindra Bagale's Tip

Start every new script with set -euo pipefail, send errors to stderr, and exit with a non-zero code on failure. Then learn the few places -e surprises you (counters, grep with no match, if conditions) so the safe header helps you instead of confusing you.

14. Frequently asked questions

Q. Why is 0 success?

There is one way to succeed and many to fail.

Q. Max exit code?

255; larger wraps around.

Q. Is set -e enough?

No; also check important steps clearly.

Q. Floating point in bash?

No; use bc or awk.

Q. let vs (( ))?

Same; (( )) is clearer.

Q. Exit code of a function?

Its last command or return N.

Q. Why 124?

timeout killed the command.

Q. Ignore one failure?

cmd || true.

15. Interview questions and answers

Beginner level

Q. What is exit code 0?

Success.

Q. Where is the last code?

$?.

Q. Add two numbers?

$((a+b)).

Q. Run b only if a works?

a && b.

Mid level level

Q. What does pipefail do?

Pipe fails if any part fails.

Q. Decimal maths?

bc or awk.

Q. Code 127?

Command not found.

Q. Errors where?

stderr with >&2.

Senior level

Q. Where does set -e not trigger?

In if tests, && || lists, and negated commands.

Q. Why does ((n++)) kill scripts?

Result 0 gives exit 1 under -e.

Q. Design retries?

Limited tries, backoff, timeout, clear final error.

Q. Exit code 137?

Killed by signal 9, often OOM.

Try at home

  1. Write a GST calculator script that takes a price and rate and prints the tax and total with 2 decimals.
  2. Add a retry function to any script that pings a website 3 times before saying it is down.

Practice Tasks

About this scenario

Vidarbha Cotton Mills is a textiles business in Nagpur. Ganesh Wankhede looks after its IT and cloud work. They count money in INR and run their AWS resources in the ap-south-1 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.

0 / 21

Easy Add

Why: BIZ jobs must stop loudly when something fails.

What to do: Ganesh Wankhede at Vidarbha Cotton Mills has variables x and y. Print their sum with arithmetic expansion.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Remainder

Why: BIZ jobs must stop loudly when something fails.

What to do: Print the remainder of n divided by 7.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Increment

Why: BIZ jobs must stop loudly when something fails.

What to do: Increase variable count by one using double parens.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Last exit code

Why: BIZ jobs must stop loudly when something fails.

What to do: Print exit= followed by the exit code of the previous command.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Strict mode

Why: BIZ jobs must stop loudly when something fails.

What to do: Turn on exit-on-error, unset-variable error and pipeline failure together using long option names.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Run if ok

Why: BIZ jobs must stop loudly when something fails.

What to do: Run make and only if it succeeds run make install.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Compare numbers

Why: BIZ jobs must stop loudly when something fails.

What to do: Test if variable free is less than 10 using double parens.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Exit code 3

Why: BIZ jobs must stop loudly when something fails.

What to do: End the script with exit status 3.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Power

Why: BIZ jobs must stop loudly when something fails.

What to do: Print 2 to the power 10 with arithmetic expansion.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Decimal result

Why: BIZ jobs must stop loudly when something fails.

What to do: Print 22 divided by 7 with 2 decimals using bc.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Only pipefail

Why: BIZ jobs must stop loudly when something fails.

What to do: Turn on only the unset-variable and pipefail options in one short set.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Or exit

Why: BIZ jobs must stop loudly when something fails.

What to do: Change to /srv/app or exit with code 1 if that fails.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Allow failure

Why: BIZ jobs must stop loudly when something fails.

What to do: Under set -e, run grep -q ERROR app.log without stopping the script if no match.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Test -ge

Why: BIZ jobs must stop loudly when something fails.

What to do: Using double brackets, test if variable n is greater than or equal to 5.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Random 1-6

Why: BIZ jobs must stop loudly when something fails.

What to do: Print a random number from 1 to 6 like a dice.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Negate

Why: BIZ jobs must stop loudly when something fails.

What to do: Print missing only if file config.yml does not exist.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium let

Why: BIZ jobs must stop loudly when something fails.

What to do: Use let to set total to price times qty.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard Pipe statuses

Why: BIZ jobs must stop loudly when something fails.

What to do: Print the exit codes of every command in the last pipeline.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard ERR trap

Why: BIZ jobs must stop loudly when something fails.

What to do: Set a trap that prints failed at line and the line number on any error.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard Retry loop

Why: BIZ jobs must stop loudly when something fails.

What to do: Try curl -fs https://api.example.in up to 3 times, stopping at the first success.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard Integer check

Why: BIZ jobs must stop loudly when something fails.

What to do: Test whether variable v contains only digits using a regex in double brackets.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

In short

  1. $(( )) for integer maths; bc/awk for decimals.
  2. 0 = success; read $? at once.
  3. PIPESTATUS shows every pipe part.
  4. && on success, || on failure.
  5. set -euo pipefail with known traps.
  6. die to stderr, retry with backoff, timeout.

Revision, comparison and interview cards

Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.

Strict mode. -e stops on errors. -u fails on unset vars. pipefail catches pipe errors. Top of the script.
Revision card: Strict mode · Download PNG · Open card page
Bash maths. Integers with $(( )). Compare with (( )). Decimals need bc. Exit code in $?.
Revision card: Bash maths · Download PNG · Open card page
$(( )) vs bc. Built in integers. / Calculator with decimals.
Comparison: $(( )) vs bc · Download PNG · Open card page
&& and or vs set -e. Per command choice. / Whole script stops.
Comparison: && and or vs set -e · Download PNG · Open card page
Where does set -e not stop?. Inside if or while tests. Left of && or ||. Add explicit checks.
Interview card: Where does set -e not stop? · Download PNG · Open card page
Why pipefail?. Pipe status = last command. A failed first step is hidden. Show all.
Interview card: Why pipefail? · Download PNG · Open card page
Common exit codes?. 0 ok, 1 error, 2 usage. 126 not executable, 127 not found. 128+N killed by signal N.
Interview card: Common exit codes? · Download PNG · Open card page
Decimals in bash?. $(( )) is integer only. Use bc or awk. Example.
Interview card: Decimals in bash? · Download PNG · Open card page

More cards: Ravi Sir's Cards.