web-dev-qa-db-ja.com

パターンが見つからないときにシェルスクリプトが途中で終了しないようにするための `set -e`および` grep`イディオム

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

私は常にset -eを使用します。多くの場合、grep1の終了ステータスがあり、パターンが見つからないことを示している場合に、grepを使用してスクリプトが実行を終了することを望まない場合があります。

この問題を解決するために私が試みたものは次のとおりです:

(私を試してください)
もしset +o pipefailで、grep 'p' | wc -lのようなものでgrepを呼び出すと、将来のメンテナがpipefailを有効にするまで、望ましい動作が得られます。また、pipefailを有効にしたいので、これは機能しません。

(IIを試してください)
sedまたはawkを使用して、パターンに一致する行のみを出力し、次にwc一致する行を出力して、一致するパターンをテストします。 sedからgrepを使用することが私の本当の問題の回避策のように思えるため、このオプションは好きではありません。

(IIIを試す)
これは私のお気に入りではありません-set +e; grep 'p'; set-eなど

どんな洞察/イディオムも最もありがたいです-ありがとう。

16
Yeow_Meng

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

set -eについて議論しているbashのmanページから:

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

19
glenn jackman