競合するプログラムの標準出力とシェルの「segfault」メッセージをキャプチャします。

競合するプログラムの標準出力とシェルの「segfault」メッセージをキャプチャします。

main.bin印刷する必要があるコンパイル済みプログラムがあります。

hello world
another line

プログラムは、最初の行を印刷した直後に分割エラーを生成します。

シェル(zsh)で実行すると、次の結果が表示されます。

Hello world
[1]    3503 segmentation fault (core dumped)  ./main.bin

しかし、stdoutの一部をリダイレクトして使用しようとすると、何もありません。これは、標準出力バッファが欠落しているためです。したがって、このunbufferツールを使用すると、それを機能させることができます。

$ unbuffer ./main.bin > tee out.log
Hello world
$ cat out.log
Hello world

さて、シェルが提供する分割エラーメッセージもキャプチャしたいと思います。

$ (sh -c ./main.bin) 2> err.log
Hello world
$ cat err.log
Segmentation fault (core dumped)

さて、どちらも別々に入手できます。しかし、一緒にキャプチャしようとすると、main.binを2回呼び出す以外に方法を見つけることができません。サブシェル内でのみバッファ解除を使用すると、分割エラーは発生しません。そして、プログラムを呼び出すだけでは出力は印刷されません。


私の目標は、プログラムの(おそらく部分的な)出力をstdoutとして印刷し、バグのあるプログラムによってシェルが生成する可能性がある分割エラー、スタックオーバーフローなどをstderrとして印刷するスクリプトを作成することです。

私の現在の解決策(もう回答を投稿しない)は、以下を含むスクリプトです。

subject="$1"
out=$(unbuffer "$subject")
err=$(sh -c "$subject" 2>&1 1>/dev/null)
echo ">o> $out"
>&2 echo ">e> $err"

スクリプトで main.bin を 2 回呼び出し、各 std{out,err} をエコーする以外に、これを達成するためのよりエレガントな方法はありますか?私はここで他の同様の項目を読みました。[1] [2] [サム]しかし、煩わしい、または私の問題に直接マッピングされていません。

答え1

リダイレクトのために&>

echo foo &> /dev/null

確認するhttps://tldp.org/LDP/abs/html/io-redirection.html、また。

答え2

1つの可能な答えは、2つの異なるスクリプトを使用することです。

  • subrun.sh:ここではstderrをファイルに抽出します。
./main.bin 2>err.log;
  • run.sh:ここでは、バッファリングされていない標準出力を収集し、各出力をその場所に印刷します。また、main.binによって提供された戻りコードを返します。
echo "">out.log>err.log
unbuffer ./subrun.sh > out.log
ret_code="$?"
cat out.log #cat to stdout
cat err.log >&2 # cat to stderr
return $ret_code # return program's return code

関連情報