助けが必要です - GNU / LINUX bashのシェルスクリプト環境で:
私はいつも使用しますset -e
。常に望むわけではありませんが、終了ステータスがパターンを見つけることができないことを示すときにgrep
スクリプトの実行を終了したいと思います。grep
1
この問題を解決する方法は次のとおりです。
(私を試してみてください)そのような方法でgrepを呼び出す
と、将来の管理者がアクティブになるまで希望の動作を得ることができます。また、私はアクティブにするのが好きなので、これは私には適していません。set +o pipefail
grep 'p' | wc -l
pipefail
pipefail
(2回試行)パターンに一致する行のみを
使用するsed
か印刷してから、一致する行を使用して一致するパターンをテストします。 toを使用することが私の実際の問題に対する解決策であると思われるので、このオプションは気に入らません。awk
wc
sed
grep
(試行III)
これは私が一番好きではありません。次のようになります。set +e; grep 'p'; set-e
どんな洞察力/慣用句にも大変感謝いたします。ありがとうございます。
答え1
条件にgrepを入れるif
こともでき、終了状態に興味がなければ|| true
。
例:grep
シェルの終了
$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233
解決策1:0以外の終了ステータスを削除する
$ 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のマニュアルページディスカッションからset -e
:
失敗したコマンドが直ちにコマンドリストの一部である場合、シェルは終了しません。しかし、または~まで キーワード、テストの一部もしまたは一生予約語、実行されたコマンドの一部 &&または│リストされた最後のコマンドの後のコマンドは除外&&または│、最後のコマンドを除くパイプライン内のすべてのコマンドまたは戻り値が次のようなコマンド!。
答え2
コマンドが失敗した場合に効果を無効にするには、他の人が言ったように、コマンドerrexit
を条件文の一部としてif
/elif
および間に使用するthen
か、論理演算子の後に使用するだけで十分です。while
until
do
&&
||
errexit
終了状態を変更せずに効果を無効にする標準イディオムは次のとおりです。
cmd && true
それはまだ戻ってきます。偽cmd
失敗したがシェルを終了しない場合。
しかし、しばしばあなたが望むのは失敗とそのerrexit
影響を無視することです。
したがって、より正式なアプローチは次のとおりです。
cmd || true
これは返されますトゥルーイ成功かどうかcmd
。
grep
返品トゥルーイ入力の1つ以上の行が一致し、エラーが発生しなかった場合偽それ以外の場合。
通常、次の目的で使用されます。
if grep -q pattern file; then
echo at least one line of file matched the pattern
do-something
fi
必要なものがあれば出力で、grep
一致がなくても構わない場合は、grep
終了ステータスを無視できます。
grep pattern file || true
しかし、あなたは捕まえられないでしょう。間違いたとえば、file
オープンできない、正規表現に構文エラーがある場合、またはgrep
その出力を書き込めない場合などです。
grep
1
不一致とエラーの場合は終了ステータスが使用され、見つからない場合は127に設定され、終了した場合は128より大きい数値に2
設定できます。したがって、値に基づいてミスマッチとエラーを明確に区別し、以下を使用してエラーのみをトリガーできる必要があります。$?
grep
$?
errexit
grep pattern file || [ "$?" -eq 1 ]
これは返されますトゥルーイ成功またはgrep
一致するものがない場合、失敗すると終了しますerrexit
([
不一致以外のエラー)$?
。1
set -o errexit
ただし、通常、非常に不安定なエラー(別名)に頼るのではなく、適切なエラー処理を実行することをお勧めしますset -e
。さまざまな障害モードを区別する必要がある場合は、grep
次のことができます。
die() { [ "$#" -eq 0 ] || printf>&2 '%s\n' "$@"; exit 1; }
grep pattern file
case $? in
(0) echo OK, match;;
(1) echo OK, no match;;
(*) handle-error; die;;
esac
答え3
pipefail
また、サブシェルを使用して設定を一時的に無効または無効にすることもできます。
( set +o pipefail ; grep 'p' ) | wc -l
または
( grep 'p' || true ) | wc -l
また、2番目のケースでは括弧が必要なので、より|
しっかりとバインドされます。||
答え4
終了ステータスに興味がある別のオプションは次のとおりです。
FOUND=$(grep whatever here) || true
if [ -z $FOUND ]; then
echo "not found"
else
echo "found"
fi