그래서 몇 가지 테스트를 실행하는 작은 스크립트가 있습니다.
javac *.java && java -ea Test
rm -f *.class
이제 문제는 스크립트를 실행할 때 ./test
테스트가 실패하더라도 rm -f *.class
성공했기 때문에 성공적인 종료 코드를 반환한다는 것입니다.
내가 원하는 것을 수행하기 위해 내가 생각할 수 있는 유일한 방법은 나에게 추악하게 느껴집니다.
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
if [ "$test_exit_code" != 0 ] ; then false; fi
그러나 이것은 일반적인 문제인 것 같습니다. 작업을 실행하고 정리한 다음 원래 작업의 종료 코드를 반환합니다.
이를 수행하는 가장 관용적인 방법은 무엇입니까(bash 또는 일반적으로 쉘에서)?
답변1
나는 다음을 선택할 것이다:
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
exit "$test_exit_code"
exit
사용 가능한데 왜 뛰어 다니나요?
당신이 사용할 수있는 trap
:
trap 'last_error_code=$?' ERR
예를 들어:
$ trap 'last_error_code=$?' ERR
$ false
$ echo $?
1
$ echo $last_error_code $?
1 0
답변2
내가 아는 한, try...finally
bash가 C와 유사한 프로그래밍 언어(있는 경우 원할 수도 있음)에 가장 가까운 것은 trap
다음과 같이 작동하는 constructor 입니다.
trap "rm -f *.class" EXIT
javac *.java && java -ea Test
스크립트가 종료되면 "rm -f *.class"가 실행됩니다. 더 복잡한 작업을 수행해야 하는 경우 함수에 넣을 수 있습니다.
cleanup() {
...
}
trap cleanup EXIT
javac *.java && java -ea Test
원한다면 이것을 대략 try...catch...finally
C의 블록 처럼 작동하는 상당히 일반적인 관용구로 바꿀 수 있습니다. 다음과 같이:
(
trap "catch_block; exit" ERR
trap finally_block EXIT
# contents of try goes here
)
이 구성에서는 대괄호로 하위 쉘을 구분합니다. 명령이 실패하면 전체 스크립트가 아닌 하위 쉘만 종료됩니다. 서브셸은 계산 비용이 다소 비싸므로 너무 많이(수백 개) 사용하지 마세요. 스크립트에 따라 쉘 기능을 사용하고 동일한 효과를 보다 효율적으로 얻을 수 있지만 trap ... RETURN
이는 연구에 따라 다릅니다.
답변3
exit
및 rm
명령을 다음과 같은 간단한 명령으로 래핑 할 수 있습니다 eval
.
java ... && java ...
eval "rm -f *.class; exit $?"
way $?
에 전달되는 값은 exit
실행 직전에 할당된 값이다.eval
답변4
접근 방식을 약간 덜 번거롭게 만들기 위해 exit
서브셸에서 다음을 사용합니다.
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
(exit $test_exit_code)