
バックグラウンドで複数のコマンドを実行するための sh ファイルを作成しています。
このファイルのどこかの行に、次のような zip ファイルを更新するコマンドがあります。
zip -d archive.zip file.txt
この file.txt は、常に archive.zip の一部であるとは限りません。そうでない場合は、シェル スクリプトは次のようにその行を中断します。
zip warning: name not matched
このファイルが存在しないことを無視して次の行に進むようにしたいのですが、どうすればこれを実現できますか?
答え1
通常、シェル スクリプトでは、エラーを生成する行があっても、シェル スクリプトの実行は停止されません。次の行に進みます。
注目すべき例外は、サブコマンドが失敗した場合にシェルを終了するためのフラグを設定した場合です。これは、スクリプトの先頭近くに「set -e」を追加することで行われることがあります。スクリプトにそのようなものが含まれている場合、スクリプト内のいずれかのコマンドがエラーを返すとスクリプトは中止されます。この場合のオプションは次のとおりです。
そのオプションを削除します。これはスクリプトの残りの部分に影響を及ぼす可能性があるため、気まぐれに実行しないでください。
スクリプトの現在のセクションのオプションをオフに切り替え、再度オンにして続行します。
set +e zip -d archive.zip file.txt set -e
何かが失敗した場合でもシェルがコマンドを成功と見なすように、失敗した行の出口を用意します。これにはさまざまな方法がありますが、最も簡単な方法の 1 つは OR 演算子を使用することです。
zip -d archive.zip file.txt || true
これは zip コマンドを実行しますが、失敗した場合は true コマンドを実行し、親シェルはそこから戻りコードを取得します (もちろん、これは成功です)。時々、
||:
少し高速でトリッキーですが魔法ではない、次のように記述されているのを目にするかもしれません。これは:
たまたまシェルに組み込まれた no-op コマンドであり、何も実行しないにもかかわらず成功エラー コードも返します。これを行う別の方法は、コマンドを で囲んでサブシェルで実行することです。これにより、サブシェル
()
内のコマンドが失敗する可能性がありますが、サブシェルはジョブを完了しているため、set を含む親スクリプトはset -e
終了しません。これは単一のコマンドには最適ではありませんが、一連のもの全体を実行する場合に役立ちます。
一方、zip によって生成されたエラー メッセージを抑制したいだけの場合は、 ( 2> /dev/null
) を使用して標準エラー ストリームを /dev/null にリダイレクトして、生成されたメッセージを抑制できます (または で閉じます2>&-
)。