It runs your bash scripts but you can also opt into correct error handling. The simple invariant is that it doesn't lose an exit code, and non-zero is fatal by default.
Oil 0.10.0 - Can Unix Shell Error Handling Be Fixed Once and For All?
https://www.oilshell.org/blog/2022/05/release-0.10.0.html
This took quite awhile, and I became aware of more error handling gotchas than I knew about when starting the project:
https://www.oilshell.org/release/latest/doc/error-handling.h...
e.g. it's impossible in bash to even see the error status of a process sub like diff <(sort left.txt) <(sort OOPS)
If you have bash scripts that you don't want to rewrite, try
1) run them with OSH
2) Add shopt --set oil:upgrade at the top to get the error handling fixes.
Tell me what happens :) https://github.com/oilshell/oil
I spent a long time on that, but the post didn't get read much. I think it's because it takes a lot of bash experience to even understand what the problem is.
How does this work? It seems magic
oil$ shopt -p oil:upgrade
shopt -s command_sub_errexit
shopt -u dashglob
shopt -s errexit
shopt -u expand_aliases
shopt -s inherit_errexit
...
Some affect parsing and some affect execution.OSH is a bash-compatible shell, from scratch! :) Let me know what happens
$ cat foo.sh
#!/usr/bin/env bash
set -euxo pipefail
declare x="$(err)"
$ shellcheck foo.sh
In foo.sh line 3:
declare x="$(err)"
^-- SC2034 (warning): x appears unused. Verify use (or export if used externally).
^-- SC2155 (warning): Declare and assign separately to avoid masking return values.
For more information:
https://www.shellcheck.net/wiki/SC2034 -- x appears unused. Verify use (or ...
https://www.shellcheck.net/wiki/SC2155 -- Declare and assign separately to ...
And the Bash man page mentions it a couple times, particularly around Pipelines, pipefail, Lists, and Compound Commands. You can also check exit status in the PIPESTATUS array.I almost never use set -o pipefail, and often not even set -e. Your scripts end up failing for mysterious reasons and it takes forever to figure out which part of which pipeline failed. Instead, I simply check the result of the end of the pipe (did it return any data? does it look valid?) and that is good enough 99% of the time.
? Expands to the exit status of the most recently executed foreground pipeline.
$ foo="$(echo foobar ; exit 3)" ; ret=$? ; echo "output: $foo" ; echo "return status: $ret"
output: foobar
return status: 3
Also, PIPESTATUS is an array with the return status from each command in a pipeline.