標準エラー出力をbash変数にリダイレクトする

標準エラー出力をbash変数にリダイレクトする

以下は、次の結果をもたらす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)

これでb​​ashスクリプトで呼び出しをラップします。連続で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

おすすめ記事