Bash – Redirecting standard error output to bash variable

bashio-redirectionstderr

Here's a C code snippet that will cause segfault:

// segfault.c

#include <string.h>

int main()
{
    memset((char *)0x0, 1, 100);
    return 1;
}

Compile it with:

gcc segfault.c -o segfault

If executed from bash:

$ ./segfault
Segmentation fault (core dumped)

Now I wrapped the call inside a bash script. There are three consecutive attempts. I want to get the error output inside the variable ret and display it.

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

If I execute the script from bash:

1) 
2) 
3)  ./segfault.sh: line 7: 28814 Segmentation fault (core dumped) ./segfault

Clearly, only the third form of invocation works. My question is, why couldn't the first two forms capture the error output?

Best Answer

It works for me with simplified bash script (only 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

The problem in your case is caused by the fact that Segmentation fault (core dumped) is not written by your program (because it is killed by kernel), but by the parent process, who get the information about the death of his child. This effect is hidden by putting it into another process and pipe with cat in your last example. You should rather rely on the exit code, then on the stderr:

$ ./segfault; echo $?
Segmentation fault (core dumped)
139
Related Question