导致错误的进程PID

导致错误的进程PID

我有这个脚本:

#!/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"

其按预期工作:

$ ./script.sh >& script.log
$ echo "$?"
139
$ cat script.log
a
Segmentation fault (core dumped)
ERR 139

(没有pipefail它会打印“a b”,没有errexit它会打印“ab c”)

但是,由于这是较大管道的一部分并在批处理系统上运行,因此可能会发生许多崩溃并且文件argv中的信息dump.?????不够。

那么:如何打印导致脚本错误的进程的 PID(以及预期的核心转储文件名),以便可以将其与其余所有进程一起记录?

崩溃的程序可能是较大管道的一部分(特别是它们可能并不总是位于管道的末尾,因此使用pipefail),并且我想避免必须用包装器代码包围每个调用,或者无法程序之间直接传送数据。

答案1

事实证明,启用作业控制可以解决问题——但前提是没有SIGSEGV陷阱,设置可以防止详细输出。

set -o errexit
set -o pipefail
set -o monitor
trap 'echo "ERR $?"' ERR
echo "hi" | ./docrash | cat
echo "not reached"

运行它可以准确地给出我正在寻找的输出,甚至更多。它打印每个子进程的 PID 并显示错误:

$ ./err.sh >& err.log
$ cat err.log
./err.sh: line 21: 25110 Done                               echo "hi"
                   25111 Segmentation fault (core dumped) | ./docrash
                   25112                                  | cat
ERR  139
$ gdb docrash core.25111
...

如果您想查看管道故障但不中止脚本,则可以组合设置:

set -o pipefail
set -o monitor
echo "hi" | ./docrash | cat
echo "pipe returned $?"

打印跟踪并继续:

$ ./err.sh
./err.sh: line 21: 25110 Done                               echo "hi"
                   25111 Segmentation fault (core dumped) | ./docrash
                   25112                                  | cat
pipe returned 139

相关内容