1. ホーム
  2. bash

[解決済み] シェルスクリプトの特定のエラーを無視する

2023-05-21 19:32:09

質問

私は、多くのエラーをスローする可能性のあるシェル スクリプトの小さなスニペットを使用しています。私は現在、すべてのエラーでグローバルに停止するようにスクリプトを設定しています。しかし、私はこの小さなサブセクションがわずかに異なることを望んでいます。

ここにスニペットがあります。

recover database using backup controlfile until cancel || true; 
auto

私は、これが最終的に "file not found" エラーを投げることを期待しています。しかし、私はこのエラーで実行を続けたいと思います。他のエラーの場合は、スクリプトを停止させたいと思います。

これを達成するための最良の方法は何でしょうか?

Bash バージョン 3.00.16

どのように解決するのですか?

特定のコマンドのエラーを無視するようにするには、次のようにします。

some-arbitrary-command || true

こうすると、スクリプトが継続される。 例えば、以下のようなスクリプトがあった場合。

$ cat foo
set -e
echo 1
some-arbitrary-command || true
echo 2

実行すると返ってくるのは

$ bash foo
1
z: line 3: some-arbitrary-command: command not found
2

がない場合は || true がなければ、コマンドラインで生成されていたはずです。

$ bash foo
1
z: line 3: some-arbitrary-command: command not found

引用元 マニュアル :

失敗したコマンドが直後のコマンドリストの一部である場合、シェルは終了しません。 の直後のコマンドリストの一部である場合、シェルは終了しません。 while または until キーワードの一部である でのテストは if ステートメントで実行されるコマンドの一部であり && または || のリストは、最後の && または || である場合、パイプラインの最後のコマンドを除くすべてのコマンド または、コマンドのリターンステータスが で反転している場合 ! . のトラップは ERR に対するトラップは、設定されている場合、シェルが終了する前に実行されます。 が終了する前に実行されます。

編集: 実行を継続するように動作を変更するために の場合のみ を実行する some-arbitrary-command 返された file not found をエラーの一部として言うことができます。

[[ $(some-arbitrary-command 2>&1) =~ "file not found" ]]

例として、次のように実行します(ファイル名が MissingFile.txt という名前のファイルは存在しません)。

$ cat foo 
#!/bin/bash
set -u
set -e
foo() {
  rm MissingFile.txt
}
echo 1
[[ $(foo 2>&1) =~ "No such file" ]]
echo 2
$(foo)
echo 3

これは以下のような出力を生成します。

$ bash foo 
1
2
rm: cannot remove `MissingFile.txt': No such file or directory

なお echo 2 は実行されましたが echo 3 は実行されませんでした。