将标准错误输出重定向到 bash 变量

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)

显然,只有第三种形式的调用有效。我的问题是,为什么前两种形式不能捕获错误输出?

Jak*_*uje 7

它适用于我的简化 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)