コマンドが成功したか失敗したかを知り、無条件で後でクリーンアップを実行する必要があります。
順次コマンドを実行するための通常のオプションはどちらもここでは適用できないようです。
$ mycmd.sh && rm -rf temp_files/ # correct exit status, cleanup fails if mycmd fails
$ mycmd.sh ; rm -rf temp_files/ # incorrect exit status, always cleans up
$ mycmd.sh || rm -rf temp_files/ # correct exit status, cleanup fails if mycmd succeeds
シェルスクリプトで実行する場合は、次のようにします。
#!/usr/bin/env bash
mycmd.sh
RET=$?
rm -rf temp_files
exit $RET
コマンドラインでこれを実現するための慣用的な方法はありますか?
スクリプトの改行は、ほとんど常にセミコロンと同等です。
mycmd.sh; ret=$?; rm -rf temp_files; exit $ret
編集に応じて:
あるいは、trap
とサブシェルを使用することもできます。
( trap 'rm -rf temp_files' EXIT; mycmd.sh )
一部の言語のコピーをお探しの場合はtry { } finally { }
、別の方法があります:trap
組み込みのbash
と他のPOSIXyシェルを使用します(help trap
)。
#!/bin/bash
# exit with this by default, if it is not set later
exit_code=0
# the cleanup function will be the exit point
cleanup () {
# ignore stderr from rm incase the hook is called twice
rm -rf "temp_files/" &> /dev/null
# exit(code)
exit $exit_code
}
# register the cleanup function for all these signal types (see link below)
trap cleanup EXIT ERR INT TERM
# run your other script
mycmd.sh
# set the exit_code with the real result, used when cleanup is called
exit_code=$?
cleanup
が呼び出されることに注意してください:
ERR
from trap's arguments from disable)zsh
内:
{mycmd.sh} always {rm -rf temp_files}
alwaysの部分は、一致のないグロブのようなエラーやスクリプトを終了するランタイム構文エラーの場合でも実行されます。
mycmd.sh && { rm -r temp_files; true; } || { rm -r temp_files; false; }
現在、&&
演算子の代わりに||
演算子とif;then
演算子のみを使用しています。しかし、「if; then」に戻る方がはるかに明確な場合もあります。コマンドラインソリューションが必要なため、これはその1つです。
このように書き直します...
$ if mycmd.sh; then { success; actions; } else { fail; actions; } fi; rm -rf temp_files/
if
がその結果を使用しますrm
はfi
の後に発生するため、無条件に実行されます。