標準出力と標準エラー出力を別の変数に入れる(2)
つづき
プロセス置換のつかえないsh
で、stdoutとstderrを別々の変数に入れる方法はあるのだろうか。
サンプル コマンド
command() { echo "[-- stdout1 --]" echo "[-- stdout2 --]" echo "[-- stderr1 --]" >&2 echo "[-- stderr2 --]" >&2 return 3 }
1. evalを使う
bashの時と同じようにevalと使う
unset out stdout stderr ret eval "stderr=\"$({ stdout=$(command);ret=$?;echo "\""; typeset -p stdout; typeset -p ret; } 2>&1);" echo $ret echo -e "stdout=$stdout\nstderr=$stderr"
結果
3 stdout=[-- stdout1 --] [-- stdout2 --] stderr=[-- stderr1 --] [-- stderr2 --]
stderrの代入でクォートしないとエラーになってしまうので、=の前に\"
を入れた。
ただ、閉じる\"
を最後の)
の後ろに書くと、typeset (declare)のダブルクォーテーションが2重になってしまう。
なので、途中にecho
を入れて"
を出力してみた。
結果、エラーにはならないけど、stderrの最後に改行が入ってしまう。
2. 区切り文字を追加する
標準出力と標準エラー出力を同じ変数に入れる。
変数に入れるときに分けるための文字列を追加する。
そして、入れたあとにsedで別々の変数に分ける。
unset out stdout stderr out=$({ echo "#####$(command)"; } 2>&1) echo $? stdout=$(echo "$out" | sed -nre '/#####/,$s/^(#####|)//p') stderr=$(echo "$out" | sed -nre '/#####/,$!p') echo -e "stdout=$stdout\nstderr=$stderr"
結果
0 stdout=[-- stdout1 --] [-- stdout2 --] stderr=[-- stderr1 --] [-- stderr2 --]
別々の変数に入れることはできたけど、 設定する文字列も考えないといけないし、あんまりよくない気がする。
戻り値をとるときはこんな感じ。
out=$({ a=$(command);b=$?;echo "#####$a";return $b; } 2>&1) echo $? 0
最初のevalを使う方法のダブルクォーテーションがなぞ。
これが解決できれば良いのだけれど、ぜんぜんわからない。
この件についてはkshがいいですね。