[HN Gopher] Getting decent error reports in Bash when you're usi...
___________________________________________________________________
Getting decent error reports in Bash when you're using 'set -e'
Author : zdw
Score : 31 points
Date : 2025-07-24 04:40 UTC (2 days ago)
(HTM) web link (utcc.utoronto.ca)
(TXT) w3m dump (utcc.utoronto.ca)
| newAccount2025 wrote:
| Why don't all shells just do this?
| inetknght wrote:
| Perhaps you underestimate just how many scripts are poorly
| written and part of your operating system.
|
| For what it's worth, I think `set -euo pipefail` should be
| default for every script, and thoroughly checked with
| shellcheck.net.
| scns wrote:
| > For what it's worth, I think `set -euo pipefail` should be
| default for every script, and thoroughly checked with
| shellcheck.net.
|
| This
| mananaysiempre wrote:
| Take care that set -o pipefail will not work on older dash
| (including IIRC the current Ubuntu LTS), and neither will set
| -o pipefail || true if set -e is in effect. (For some reason
| that I'm too lazy to investigate, a failing set invocation
| will crash the script immediately rather than proceed into
| the second branch.) The best I could think of to
| opportunistically enable it was to use a subshell:
| if (set -o pipefail 2>/dev/null); then set -o pipefail; fi
|
| Or you can just target bash, I guess.
|
| (I rather dislike shellcheck because it combines genuine
| smells with opinions, such as insisting on $(...) instead of
| `...`. For the same reason, with Python I regularly use
| pyflakes but can't stand flake8. But to each their own.)
| imcritic wrote:
| That's a pitfall 60
|
| https://mywiki.wooledge.org/BashPitfalls#set_-euo_pipefail
| eikenberry wrote:
| What about for `/bin/sh`, i.e. posix compliant shells like
| dash?
| koolba wrote:
| Automatically leaking the line number and command, even to
| stderr is not a sane default.
| Grimeton wrote:
| You can just do trap 'caller 1' ERR
|
| should do the same thing. Also you should set "errtrace" (-E) and
| possibly "nounset" (-u) and "pipefail".
| o11c wrote:
| FWIW, I've grown the following which handles a few more cases.
| For some reason I wasn't aware of `caller` ...
| set -e is-oil() { test -n
| "$OIL_VERSION" } set -E || is-oil
| trap 'echo "$BASH_SOURCE:$LINENO: error: failure during early
| startup! Details unavailable."' ERR
| magic_exitvalue=$(($(kill -l CONT)+128)) backtrace()
| { { local status=$?
| if [ "$status" -eq "$magic_exitvalue" ] then
| echo '(omit backtrace)' exit
| "$magic_exitvalue" fi local max
| file line func argc argvi i j echo
| echo 'Panic! Something failed unexpectedly.' "(status $status)"
| echo 'While executing' "$BASH_COMMAND" echo
| echo Backtrace: echo
| max=${#BASH_LINENO[@]} let max-- # The top-most
| frame is "special". argvi=${BASH_ARGC[0]}
| for ((i=1;i<max;++i)) do
| file=${BASH_SOURCE[i]}
| line=${BASH_LINENO[i-1]} func=${FUNCNAME[i]}
| argc=${BASH_ARGC[i]} printf '%s:%d: ... in
| %q' "$file" "$line" "$func" # BASH_ARGV: ...
| bar foo ... # argvi ^
| # argvi+argc ^ for ((j=argc-1;
| j>=0; --j)) do printf
| ' %q' ${BASH_ARGV[argvi+j]} done
| let argvi+=argc || true printf '\n'
| done if true then
| file=${BASH_SOURCE[i]}
| line=${BASH_LINENO[i-1]} printf '%s:%d: ...
| at top level\n' "$file" "$line" fi }
| >&2 exit "$magic_exitvalue" unreachable
| } shopt -s extdebug trap 'backtrace' ERR
| edoceo wrote:
| What the hell. This is cool and all but I'm looking at it as a
| signal I should move up one tier in language (eg: to Perl, PHP,
| Python or Ruby)
| chubot wrote:
| I think you should be able to get rid of the is-oil part - it
| was implemented last year $ osh -c 'set -E;
| set -o |grep errtrace' set -o errtrace
|
| I'd be interested in any bug reports if it doesn't behave the
| same way
|
| (The Oils runtime supports FUNCNAME BASH_SOURCE and all that,
| but there is room for something much better. It actually has a
| JSON crash report with a shell stack dump, but it probably
| needs some polish.)
| bjackman wrote:
| But trap doesn't "stack" (like e.g. defer in Go) so if you do
| this it's not available for other purposes like cleanup
___________________________________________________________________
(page generated 2025-07-26 23:00 UTC)