以下は、次の結果をもたらすCコードの断片ですsegfault
。
// segfault.c
#include <string.h>
int main()
{
memset((char *)0x0, 1, 100);
return 1;
}
コンパイル:
gcc segfault.c -o segfault
Bashで実行している場合:
$ ./segfault
Segmentation fault (core dumped)
これで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
Bashでスクリプトを実行する場合:
1)
2)
3) ./segfault.sh: line 7: 28814 Segmentation fault (core dumped) ./segfault
明らかに、3番目の呼び出し形式のみが機能します。私の質問は、最初の2つのフォームがエラー出力をキャプチャできないのはなぜですか?
ベストアンサー1
単純化された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
あなたの場合、問題はSegmentation fault (core dumped)
プログラムがあなたのプログラムによって書かれているのではなく(カーネルによって終了されるため)、子プロセスの終了に関する情報を取得する親プロセスによって書かれているという事実によって引き起こされます。cat
前の例では、この効果を別のプロセスに配置してパイピングして非表示にしました。終了コードと以下を使用する必要がありますstderr
。
$ ./segfault; echo $?
Segmentation fault (core dumped)
139