나중에 사용할 수 있도록 종료 코드 저장

나중에 사용할 수 있도록 종료 코드 저장

그래서 몇 가지 테스트를 실행하는 작은 스크립트가 있습니다.

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...finallybash가 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...finallyC의 블록 처럼 작동하는 상당히 일반적인 관용구로 바꿀 수 있습니다. 다음과 같이:

(
  trap "catch_block; exit" ERR
  trap finally_block EXIT
  # contents of try goes here
)

이 구성에서는 대괄호로 하위 쉘을 구분합니다. 명령이 실패하면 전체 스크립트가 아닌 하위 쉘만 종료됩니다. 서브셸은 계산 비용이 다소 비싸므로 너무 많이(수백 개) 사용하지 마세요. 스크립트에 따라 쉘 기능을 사용하고 동일한 효과를 보다 효율적으로 얻을 수 있지만 trap ... RETURN이는 연구에 따라 다릅니다.

답변3

exitrm명령을 다음과 같은 간단한 명령으로 래핑 할 수 있습니다 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)

관련 정보