xonsh
xonsh copied to clipboard
Implement pipefail and errexit
I want to know when a command other then the last command in the pipeline fails for any reason. If a command in the middle of a pipeline fails, the last command simply sees a EOF in its stdin. In many cases this will result in the last command returning success. Silently ignoring such errors can lead to all kinds of data loss, data corruption, truncation and other badness. Ideally any unhandled errors should terminate the script.
bash has pipefail:
#!/usr/bin/env bash
set -o errexit -o pipefail
echo one
false | true
echo two
VVV
one
Note: the above example does not print "two"
#!/usr/bin/env xon.sh
$RAISE_SUBPROC_ERROR = True
echo one
false | true
echo two
VVV
one
two
For community
⬇️ Please click the 👍 reaction instead of leaving a +1
or 👍 comment
More context: Executing an external command can fail for a million different reasons. Here are some examples:
- The external command is not installed
- It encounters an internal bug and fails fast and loud
- It receives bad input due to a bug in my script
- An admin kills it
- The OOM Killer kills it https://linuxwheel.com/oom-killer-explained/
- It tries to talk to another process possibly on a different machine and that fails for any reason
- It uses a temporary file for internal buffering and /tmp is full
- It tries to read or write a file and that fails for any reason
A robust script can not afford to ignore the possibility that any of the external commands it executes may fail. Often the right choice of action is to fail fast because the code that follows requires that the preceding commands executed successfully.
Unix-y pipelines have an issue:
foo | bar
If foo
exits successfully bar
sees EOF. If foo
fails bar
also sees EOF. bar
has no way to know whether foo
failed or not. In many cases bar
will exit successfully even if foo
fails. The script has to detect that and fail. This is why you often see set -o errexit -o pipefail
in bash.
Unfortunately set -o errexit
is very broken in bash which is why I'm looking for a different shell.
I also miss this feature, which is quite important in my opinion. Two use cases are
pv input | foo
(pv = pipe viewer, it generates progress output at stderr)
and
foo | tee logfile
I guess these use cases are rather common, but the lack of some pipefail equivalent makes them painful with xonsh.