summaryrefslogtreecommitdiff
path: root/prompts/skills/bash-best-practices/reference/error-handling.md
blob: ef06460ef47d27500dd6da52573d515dd024bc81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Bash Error Handling and Safety

## Paranoid mode (`set -e`)

Enable `set -e` so the script exits on any unexpected non-zero status. Temporarily disable it around commands that are allowed to fail.

```bash
set -e

some_function () {
    # ... critical code ...

    set +e
    grep ... || true
    local -i ec=$?
    set -e

    if (( ec != 0 )); then
        : # handle expected non-match
    fi
}
```

## `pipefail`

Use `set -o pipefail` so the pipeline returns the status of the last command that exited non-zero, not just the last command.

```bash
set -o pipefail
command1 | command2 | command3
```

## `PIPESTATUS`

Capture `PIPESTATUS` into an array immediately after a pipeline to inspect each stage's exit code.

```bash
tar -cf - ./* | ( cd "$dir" && tar -xf - )
return_codes=("${PIPESTATUS[@]}")
if (( return_codes[0] != 0 )); then
    echo 'tar failed' >&2
fi
```

## Arithmetic and Comparisons

Use arithmetic evaluation `(( ))` or numeric comparison operators (`-gt`, `-lt`, `-eq`) to avoid unintended lexicographical comparison.

```bash
# Wrong: lexicographical
if [[ "$my_var" > 3 ]]; then

# Right: numeric
if (( my_var > 3 )); then
if [[ "$my_var" -gt 3 ]]; then
```

## Restricted Bash

Use `rbash` as a coarse sandbox for highly constrained environments.

```bash
rbash -c 'echo hi'
```

See `man bash` (RESTRICTED SHELL) for details and caveats.