Hol*_*ock 7 bash io-redirection stderr
这是一个 C 代码片段,它将导致segfault:
// segfault.c
#include <string.h>
int main()
{
memset((char *)0x0, 1, 100);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
编译它:
gcc segfault.c -o segfault
Run Code Online (Sandbox Code Playgroud)
如果从 bash 执行:
$ ./segfault
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
现在我将调用封装在 bash 脚本中。连续尝试了3次。我想获取变量内的错误输出ret并显示它。
#!/bin/bash
# segfault.sh
ret=`./segfault 2>&1`
echo "1) " $ret
ret=`eval ./segfault 2>&1`
echo "2) " $ret
ret=`eval ./segfault 2>&1 | cat`
echo "3) " $ret
Run Code Online (Sandbox Code Playgroud)
如果我从 bash 执行脚本:
1)
2)
3) ./segfault.sh: line 7: 28814 Segmentation fault (core dumped) ./segfault
Run Code Online (Sandbox Code Playgroud)
显然,只有第三种形式的调用有效。我的问题是,为什么前两种形式不能捕获错误输出?
它适用于我的简化 bash 脚本(仅限stderr):
$ cat seg.sh
#!/bin/bash
echo "Segfault" 1>&2
$ test=`./seg.sh`; echo "x$test"
Segfault
x
$ test=`./seg.sh 2>&1`; echo "x$test"
xSegfault
$ test=`eval ./seg.sh 2>&1`; echo "x$test"
xSegfault
Run Code Online (Sandbox Code Playgroud)
您的情况下的问题是由于Segmentation fault (core dumped)不是由您的程序编写的(因为它被内核杀死),而是由获取有关其孩子死亡信息的父进程引起的。cat在上一个示例中,通过将其放入另一个进程和管道中来隐藏此效果。您应该更依赖于退出代码,然后依赖于stderr:
$ ./segfault; echo $?
Segmentation fault (core dumped)
139
Run Code Online (Sandbox Code Playgroud)