명령이 성공했는지 실패했는지 확인한 다음 일부 정리 작업을 무조건 실행해야 합니다.
순차 명령을 실행하기 위한 일반적인 옵션은 여기에 적용되지 않는 것 같습니다.
$ 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
이러한 모든 명령을 세미콜론으로 연결하는 것보다 명령줄에서 이를 수행하는 더 관용적인 방법이 있습니까?
답변1
스크립트의 줄 바꿈은 거의 항상 세미콜론과 동일합니다.
mycmd.sh; ret=$?; rm -rf temp_files; exit $ret
편집자에 대한 답변:
trap
또는 다음과 같이 및 하위 쉘을 사용할 수 있습니다 .
( trap 'rm -rf temp_files' EXIT; mycmd.sh )
답변2
일부 언어의 복사본을 찾고 있다면 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
이 이름은 다음과 같습니다 .
- 이 스크립트를 SIGINT 또는 SIGTERM으로 보내거나 CTRL-C(SIGINT)를 누르는 경우
- 이 스크립트가 정상적으로 종료되고 0을 반환하는 경우
- mycmd.sh가 0이 아닌 상태로 종료되는 경우(아마도 원하는 상태가 아닐 수 있음 -
ERR
비활성화하려면 트랩 매개변수에서 제거하세요.)
답변3
존재하다 zsh
:
{mycmd.sh} always {rm -rf temp_files}
이것언제나이 섹션은 오류(예: 일치하지 않는 glob 또는 런타임 구문 오류)가 발생하여 스크립트를 종료하는 경우에도 실행됩니다.
답변4
이제 대신 &&
and 연산자를 사용합니다 . 그러나 때로는 "if; then"으로 돌아가는 것이 더 명확할 때도 있습니다. 명령줄 솔루션이 필요하기 때문에 이는 그 중 하나입니다.||
if;then
이렇게 다시 쓸텐데...
$ if mycmd.sh; then { success; actions; } else { fail; actions; } fi; rm -rf temp_files/
- mycmd.sh를 실행하고
if
그 결과를 사용하십시오. - 중괄호는 내부의 여러 명령 목록이 블록으로 처리되도록 보장하고 명확성을 향상시킵니다. 각 명령(마지막 명령 포함) 뒤의 중괄호와 세미콜론 주위의 공백은 필수입니다.
rm
이후에 발생 하므로fi
무조건 실행됩니다.