このスクリプトは「後」にエコーしません。
#!/bin/bash -e
echo "before"
echo "anything" | grep e # it would if I searched for 'y' instead
echo "after"
exit
また、-e
シバン行のオプションですが、エラーが発生した場合にスクリプトが停止するように保持しておきたいと思います。私はgrepが一致しないものを見つけるのをエラーとは考えていません。どのように私はそれがそれほど急激に終了するのを防ぐことができますか?
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
は常にゼロを返します)。
安全かつオプションで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はエラーを意味します。
別のオプションは、パイプラインに別のコマンドを追加することです-失敗しないもの:
echo "anything" | grep e | cat
cat
がパイプラインの最後のコマンドになったため、パイプラインが失敗したかどうかを判断するために使用されるのは、cat
ではなくgrep
の終了ステータスです。
#!/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の効果のないコマンドです。
別のオプション:
...
set +e
echo "anything" | grep e
set -e
...