쉘 명령(스크립트 아님)에서 "보장"/"최종" 기능을 얻으시겠습니까?

쉘 명령(스크립트 아님)에서 "보장"/"최종" 기능을 얻으시겠습니까?

명령이 성공했는지 실패했는지 확인한 다음 일부 정리 작업을 무조건 실행해야 합니다.

순차 명령을 실행하기 위한 일반적인 옵션은 여기에 적용되지 않는 것 같습니다.

$ 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무조건 실행됩니다.

관련 정보