I have this script:
#!/bin/bash
# -> dump.$pid
ulimit -c unlimited
# trap ERR
set -o errexit
# also trap error in the middle of a pipe (1)
# otherwise it will only trap the error on (2)
set -o pipefail
trap 'echo "ERR $?"' ERR
echo "a"
echo "1" | ./crash | cat
echo "b"
echo "2" | ./crash
echo "c"
Which works as intended:
$ ./script.sh >& script.log
$ echo "$?"
139
$ cat script.log
a
Segmentation fault (core dumped)
ERR 139
(without pipefail
it would print "a b", without errexit
it would print "a b c")
However, since this is part of a larger pipeline and run on a batch system, a number of crashes might occur and the argv
information in the dump.?????
file is not enough.
So: How do I print the PID (and therefore the expected core dump filename) of the process that caused the error from my script, so that it can be logged with all the rest?
The crashing programs may be part of larger pipelines (especially they may not always be at the end of a pipeline, therefore the use of pipefail
), and I'd like to avoid having to surround each invocation with wrapper code, or not being able to pipe data directly between programs.
PIPESTATUS
contain the information you need?$?
in theERR
trap already; in combination withBASH_COMMAND
I could figure out which part of the pipe failed as a command string, but not the PIDs of the children actually invoked. (similar problem with trappingSIGCHLD
: how can I get the child PID? Bash just handled the child, it must know the PID somewhere, right?)