修正する

修正する

stdout私のスクリプトには、との出力を生成する複雑なコマンドがありますstderr。 2つを別々の変数としてキャプチャする必要があります。

#!/bin/sh
A=$(command)

stderr変数で「キャプチャ」する方法はB

andのいくつかのバリエーションを試しましたが、うまくいきません2>&1read

A=$(some_command) 2>&1 | read B
echo $B

または

{ OUT="$(command)" 2>&1 | read B ; }
echo $B

動作する唯一の方法は、一時ファイルstderrにリダイレクトして再読み込みすることです。しかし、これは汚いハッキングのように見えます。一時ファイルを使用せずにこれを行う方法はありますか?

修正する

明確にするために、stdout両方ともstderr複数行で出力されます。

ベストアンサー1

正直なところ、ファイルを使用するのはおそらく最も簡単な方法です。しかし、ここではstdout単一行変数として使用し、stderr1行か(または平面化)に関係ないと仮定していくつかの仮定をしましょう。それでは、簡単なスクリプトでテストしてみましょう。ここで、「2」はstderrstdoutに移動し、他の行はstdoutに移動します。

> cat outerr.sh
echo 1
echo 2 >&2
echo 3
> ./outerr.sh
1
2
3
> ./outerr.sh 2>/dev/null
1
3

これにより、次のことができます。

(echo $(./outerr.sh) # Collect and flatten the stdout output 
                     # Meanwhile stderr flows through the pipe
) 2>&1|{
        read err     # This assumes stderr is one line only
        read out
        echo "err=$err"
        echo "out=$out"
}

あるいは、stderrが複数減らせる場合

(echo $(./outerr.sh) # Collect and flatten the stdout output 
                     # Meanwhile stderr flows through the pipe
) 2>&1|tac|{         # reverse the output so the stdout line comes first
        read out
        err=$(tac)   # reverse lines again, back to the original line order
        echo "err=$err"
        echo "out=$out"
}

出力を含む

err=2
out=1 3

行を保持する必要がある場合は、stdout\n改行を含めるか、ファイルを再利用して戻すことができます。

おすすめ記事