web-dev-qa-db-ja.com

nomatchの場合にgrepが終了しないようにします

このスクリプトは「後」にエコーしません。

#!/bin/bash -e

echo "before"

echo "anything" | grep e # it would if I searched for 'y' instead

echo "after"
exit

また、-eシバン行のオプションですが、エラーが発生した場合にスクリプトが停止するように保持しておきたいと思います。私はgrepが一致しないものを見つけるのをエラーとは考えていません。どのように私はそれがそれほど急激に終了するのを防ぐことができますか?

33
iago-lito
echo "anything" | grep e || true

説明:

$ echo "anything" | grep e
### error
$ echo $?
1
$ echo "anything" | grep e || true
### no error
$ echo $?
0
### DopeGhoti's "no-op" version
### (Potentially avoids spawning a process, if `true` is not a builtin):
$ echo "anything" | grep e || :
### no error
$ echo $?
0

「||」 「または」を意味します。コマンドの最初の部分が「失敗」した場合(「grep e」がゼロ以外の終了コードを返すことを意味します)、「||」の後の部分実行され、成功し、終了コードとしてゼロを返します(trueは常にゼロを返します)。

36
John N

安全かつオプションでgrepメッセージを送信する堅牢な方法:

echo something | grep e || [[ $? == 1 ]] ## print 'something', $? is 0
echo something | grep x || [[ $? == 1 ]] ## no output, $? is 0
echo something | grep --wrong-arg e || [[ $? == 1 ]] ## stderr output, $? is 1

posixマニュアル によると、終了コード1は行が選択されていないことを意味し、> 1はエラーを意味します。

15
James Z.M. Gao

別のオプションは、パイプラインに別のコマンドを追加することです-失敗しないもの:

echo "anything" | grep e | cat

catがパイプラインの最後のコマンドになったため、パイプラインが失敗したかどうかを判断するために使用されるのは、catではなくgrepの終了ステータスです。

11
roelvanmeer

解決

#!/bin/bash -e

echo "before"

echo "anything" | grep e || : # it would if I searched for 'y' instead

echo "after"
exit

説明

set -eまたはset -o errexit

パイプライン(単一のシンプルコマンドで構成されている場合があります)、リスト、または複合コマンドの場合は、すぐに終了します=(上記のShell GRAMMARを参照)、ゼロ以外のステータスで終了します。失敗したコマンドがwhileまたはuntilキーワードの直後のコマンドリストの一部であり、テストの一部であるifまたはElif予約語、&&または||リストで実行されるコマンドの一部、ただし最後の&&または||に続くコマンド、パイプライン内の任意のコマンド最後、またはコマンドの戻り値が!で反転されている場合。 -eが無視されているときにコマンドが失敗したために、サブシェル以外の複合コマンドがゼロ以外のステータスを返した場合、シェルは終了しません。 ERRのトラップは、設定されている場合、シェルが終了する前に実行されます。このオプションは、シェル環境と各サブシェル環境に個別に適用され(上記のCOMMAND EXECUTION ENVIRONMENTを参照)、サブシェル内のすべてのコマンドを実行する前にサブシェルが終了する場合があります。

さらに、:はBashの効果のないコマンドです。

5
Cyker

別のオプション:

...
set +e
echo "anything" | grep e
set -e
...
4
Jeff Schaller