シェルでコマンドの標準出力と標準エラー出力を別の変数に入れる
コマンドの標準出力と標準エラー出力を別々の変数に格納する
サンプルのコマンド
function command { echo "[-- stdout --]" echo "[-- stderr --]" >&2 return 3 }
1. 標準エラー出力をファイルに書く
ファイルに書いてあとから読む方法は、
わかりやすいし、コマンドの戻り値もとれる
tmpfile=$(mktemp --tmpdir=.) stdout=$(command 2>$tmpfile) echo $? stderr=$(cat $tmpfile) rm $tmpfile echo stdout=$stdout stderr=$stderr
結果
3 stdout=[-- stdout --] stderr=[-- stderr --]
でも、ファイルをつくりたくない。
2. eval、コマンド置換、プロセス置換を使う
こんな感じにコマンド置換やプロセス置換をしてeval
に渡す
stdout= stderr= eval "$((command) 2> >(stderr=$(cat);typeset -p stderr) > >(stdout=$(cat);typeset -p stdout))" echo $? echo stdout=$stdout stderr=$stderr
結果
0 stdout=[-- stdout --] stderr=[-- stderr --]
eval
でdeclare -- stdout="xx
とdeclare -- stderr="xx"
が実行されることで変数に設定される
※typeset -p name
は declare -- name=value"
を出力する
戻り値はとれない。 別の変数に設定すればとれる。
stdout= stderr= eval "$((command) 2> >(stderr=$(cat);typeset -p stderr) > >(stdout=$(cat);typeset -p stdout);ret=$?;typeset -p ret)" echo stdout=$stdout stderr=$stderr ret=$ret
結果
stdout=[-- stdout --] stderr=[-- stderr --] ret=3
戻り値が別の変数になってしまうのが残念。
3. kshを使う
kshだとシンプルにできる
stdout= stderr= stderr=${ { stdout=$(command); } 2>&1; } echo $? echo stdout=$stdout stderr=$stderr
結果
3 stdout=[-- stdout --] stderr=[-- stderr --]
戻り値もとれるし、良い。