5

私が本当にやりたいことは、パイプライン内のすべてが成功したことを確認し、最後の stdin を変数に割り当てることだけです。次の簡単なシナリオを考えてみましょう。

x=`exit 1|cat`

を実行するdeclare -aと、次のように表示されます。

declare -a PIPESTATUS='([0]="0")'

に気付くには何らかの方法が必要なexit 1ので、次のように変換しました。

exit 1|cat|xargs -I {} x={}

そしてdeclare -a私にくれました:

declare -a PIPESTATUS='([0]="1" [1]="0" [2]="0")'

それが私が望んでいたことなので、exit 1起こらなかった場合に何が起こるかを確認しようとしました:

echo 1|cat|xargs -I {} x={}

しかし、それは失敗します:

xargs: x={}: No such file or directory

xargs を に割り当てる方法はあります{}x? PIPESTATUS作業を行い、標準入力を変数に割り当てる他の方法はどうですか?

注: これらの例は単純化されています。exit 1echo 1または を実際に行っているわけではありませんがcat、これらのコマンドを使用して単純化して、特定の問題に集中できるようにしました。

4

6 に答える 6

3

バッククォート (または優先$()) を使用すると、サブシェルでこれらのコマンドを実行しています。PIPESTATUSあなたが得ているのは、サブシェルのパイプされたコマンドではなく、割り当てのためのものです。

を使用するxargsと、シェルについて何も知らないため、変数の割り当てを行うことができません。

からステータスset -o pipefailを取得できます$?

于 2010-08-10T21:03:57.823 に答える
3

xargs呼び出すすべてのコマンドと同様に、子プロセスで実行されます。したがって、シェルの環境に影響を与えることはできません。

名前付きパイプ ( mkfifo)、または bash のread機能で何かできるのではないでしょうか?

編集:

おそらく、出力をファイルにリダイレクトするだけで、PIPESTATUS を使用できます。

command1 | command2 | command3 >/tmp/tmpfile
## Examine PIPESTATUS
X=$(cat /tmp/tmpfile)
于 2010-08-10T16:27:15.290 に答える
0

どうですか...

read x <<<"$(echo 1)"
read x < <(echo 1)

echo "$x"
于 2010-08-10T21:10:32.760 に答える
0

新しい配列を作成しないのはなぜですか?

IFS=$'\n' read -r -d '' -a result < <(echo a | cat | cat; echo "PIPESTATUS='${PIPESTATUS[*]}'" )
IFS=$'\n' read -r -d '' -a result < <(echo a | exit 1 | cat; echo "PIPESTATUS='${PIPESTATUS[*]}'" )

echo "${#result[@]}"
echo "${result[@]}"
echo "${result[0]}"
echo "${result[1]}"
于 2010-08-11T10:46:00.840 に答える
0

すでにいくつかの役立つソリューションがあります。上記の質問に一致する例が実際にあったことがわかりました。とにかく十分に近い。

このことを考慮:

 XX=$(ls -l *.cpp | wc -l  | xargs -I{} echo {})
 echo $XX
 3

つまり.cpp、作業ディレクトリに 3 つのファイルがありました。今$XXは 3 で、その結果をスクリプトで利用できます。xargsこの例では実際には必要ないため、不自然です。しかし、それは機能します。

質問の例では...

x=`exit 1|cat`

私はそれがあなたに指定されたものを与えるとは思わない. が言及さexitれる前にサブシェルを終了します。catまた、その点については、

私は次のようなものから始めるかもしれません

declare -a PIPESTATUS='([0]="0")'
x=$?

x最後のコマンドからのステータスになりました。

于 2018-11-20T12:51:17.180 に答える