web-dev-qa-db-ja.com

単一のパイプされたコマンドのpipefailの設定

次のように、BASH以外のスクリプト(PHPスクリプト))からパイプでシェルコマンドをいくつか実行する必要があります。

command1 | command2 | command3

したがって、command1はゼロ以外の終了コードで失敗し、他の各コマンドも失敗します。これまでのところ、私が思いついたのは:

set -o pipefail && command1 | command2 | command3

ただし、ターミナルからは正常に実行されますが、スクリプトから実行すると次のようになります。

sh:1:set:Illegal option -o pipefail

19
Desmond Hume

Bashコマンドラインからサブシェルを呼び出して、後でpipefailが設定されないようにする必要があります。

$ (set -o pipefail && command1 | command2 | command3)

これにより、pipefailオプションの効果が、括弧(...)によって作成されるサブシェルに制限されます。

実際の例:

$ (set -o pipefail && false | true) && echo pipefail inactive || echo pipefail active
pipefail active

-cオプションを指定して明示的なShell呼び出しを使用する場合、bashまたはshエイリアスをbashに使用することで、サブシェルは必要ありません。

$ bash -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active
$ sh -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active

あなたのshpipefailオプションを受け入れないため、bashの古いバージョンまたは変更されたバージョンであるか、または実際には他のシェルであると想定する必要があります完全に。

18
thkala

なぜそれが上記で言及されなかったかはわかりませんが、set +o pipefailを使用してpipefailを明示的に設定解除することが可能です。

set -o pipefail
command1 | command2 | command3
set +o pipefail

フラグメントを実行していて、pipefailがすでに設定されているかどうか不明な場合は、これを以前に提案されたサブシェルで使用できます。

# explicitly execute with pipefail set
(set -o pipefail ; command1 | command2 | command3 )
# explicitly execute with pipefail unset
(set +o pipefail ; command1 | command2 | command3 )
6
robbat2

$(command1)を$と組み合わせて使用​​できますか? :

a=$(echo "a")
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

「abc」を印刷します

a=$(ls unexitingDir)
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

「」を印刷します。

「[$?-eq 0] &&」は、前のコマンドが成功した場合にのみ、次のコマンドが実行されることを意味します。

それはあなたの質問には答えませんが、それはあなたの問題の解決策です。

0
cglacet