捕获崩溃程序的标准输出和 shell 的“段错误”消息

捕获崩溃程序的标准输出和 shell 的“段错误”消息

我有一个编译后的程序main.bin应该打印:

hello world
another line

该程序在打印第一行后立即生成分段错误。

如果我在 shell (zsh) 中运行它,我会得到以下结果:

Hello world
[1]    3503 segmentation fault (core dumped)  ./main.bin

但是,当我尝试重定向并使用部分标准输出时,什么也没有。这是由于丢失了标准输出缓冲区。因此,使用该unbuffer工具,我可以让它正常工作:

$ unbuffer ./main.bin > tee out.log
Hello world
$ cat out.log
Hello world

好的。现在我还想捕获 shell 给出的分段错误消息:

$ (sh -c ./main.bin) 2> err.log
Hello world
$ cat err.log
Segmentation fault (core dumped)

好的,我可以分别获取两者。但是当我尝试将它们捕获在一起时,除了调用 main.bin 两次之外,我找不到其他方法。仅在子 shell 中使用 unbuffer 不会产生分段错误。并且单独调用该程序不会打印输出。


我的目标是制作一个脚本,在 stdout 中打印程序的(可能是部分)输出,并在 stderr 中打印 shell 由于有错误的程序可能生成的任何分段错误、堆栈溢出等。

我当前的解决方案(不再是,我发布了答案)是一个包含以下内容的脚本:

subject="$1"
out=$(unbuffer "$subject")
err=$(sh -c "$subject" 2>&1 1>/dev/null)
echo ">o> $out"
>&2 echo ">e> $err"

除了在脚本中调用 main.bin 两次并回显每个 std{out,err} 之外,是否有更优雅的方法来实现此目的?我一直在这里阅读其他类似的条目[1] [2] [3],但它们很麻烦,或者不能直接映射到我的问题。

答案1

用于&>重定向!

echo foo &> /dev/null

查看https://tldp.org/LDP/abs/html/io-redirection.html, 也。

答案2

一个可能的答案是使用两个不同的脚本:

  • subrun.sh:这里我将stderr提取到文件中
./main.bin 2>err.log;
  • run.sh:这里我收集未缓冲的标准输出,并将每个输出打印到相应的位置。另外,返回main.bin给出的返回码
echo "">out.log>err.log
unbuffer ./subrun.sh > out.log
ret_code="$?"
cat out.log #cat to stdout
cat err.log >&2 # cat to stderr
return $ret_code # return program's return code

相关内容