パターンが見つからないときにシェルスクリプトからの早期終了を防ぐための「set -e」および「grep」イディオム


15

必要なヘルプ-GNU / LINUX bashでのシェルスクリプトのコンテキストで:

私はいつも使用しますset -e。多くの場合、パターンが見つからないことを示す終了ステータスがあるgrep場合、スクリプトの実行を終了させたいとは思わないでしょう。grep1

この問題を解決しようとしたのは次のとおりです。

(Iを試してみてください)
の場合set +o pipefailと同様なものとgrepの呼び出しgrep 'p' | wc -l将来のメンテナが有効になるまで、私は目的の動作を取得しますpipefail。また、有効にするのpipefailが好きなので、これはうまくいきません。

(IIしてみてください)
を使用しsed、またはawkその後、およびのみパターンに一致する行を印刷wcマッチしたパターンのための試験に適合ライン。sedto を使用することgrepは私の本当の問題の回避策のように思えるので、私はこのオプションが好きではありません。

(トライIII)
これは私の一番好きではありません-次のようなものです:set +e; grep 'p'; set-e

どんな洞察/イディオムも最も高く評価されるでしょう-ありがとう。

回答:


19

grepをif条件に置くことができます|| true。終了ステータスを気にしない場合は、を追加します。

例:grepシェルを殺す

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

解決策1:ゼロ以外の終了ステータスを破棄する

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

解決策2:終了ステータスを明示的にテストする

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

議論するbashのmanページからset -e

失敗したコマンドがwhileまたはuntil キーワードの直後のコマンドリストの一部、ifまたはelif予約語の後に続くテストの一部、&&または││リストで実行されるコマンドの一部である 場合、シェルは終了しません最終&&または││に続くコマンド、パイプライン内の最後以外のコマンド、またはコマンドの戻り値が


長い間bashが-eを正しく実装しなかったことを考えると、ドキュメントがまだ正しくない可能性があります。テキストはbash-3.xのマニュアルページと同じように見えるので、注意してください:bash4.0より前のすべてのbashバージョンは-eを誤って実装していました。
気味悪い

また、ノートPOSIX標準が同様に間違っていたとして、我々は2009年に-eとエラー処理のためのPOSIXのテキストを変更したこと
シリー

1
@schily -eの「正しい」動作、bash <4の動作の違い、POSIXでの変更点を見つけられる場所へのポインタを教えてください。
zwol

bash-3のバグはmake、エラーで常に終了するとは限らないため、基本的に使用できなくなります。関連するPOSIXの議論については、austingroupbugs.net
schily

@schilyもっと具体的にお願いします。
zwol
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.