오류 상태를 저장하고, 추가 코드를 실행하고, 오류 상태를 원래 오류 상태로 설정하는 작은 스크립트를 작성하고 싶습니다. Bash에서는 다음과 같습니다:
<< some command >>; _EXIT=$?;( <<other code here>> ;exit $_EXIT)
그러나 필요한 코드는 bash, zsh, csh 또는 tcsh에서 실행되는지 여부에 관계없이 실행될 수 있습니다. 어떤 쉘을 사용할지는 사용자가 결정하기 때문에 미리 알 수 없습니다. <<a 명령>>도 사용자가 결정합니다.
<< 다른 코드 >>가 모든 쉘에서 작동할 것이라고 가정하는 것은 안전하지만, 파일에 쓸 수 있다고 가정하는 것은 안전하지 않습니다(따라서 파일에 넣는 것은 작동하지 않습니다).
배경
GNU Parallel은 사용자가 결정한 쉘에서 사용자가 지정한 명령을 실행합니다. 명령이 완료된 후 GNU Parallel은 일부 정리 작업을 수행해야 합니다. 동시에 GNU Parallel은 사용자가 제공한 명령의 종료 값을 기억해야 합니다. 위 스니펫 이전에 실행된 코드는 사용자가 제공한 명령이었습니다. <<다른 코드>>는 정리 코드입니다.
답변1
이 답변은 bash와 같은 쉘과 csh와 같은 쉘 모두에서 작동하며 Perl이 필요하지 않습니다.
sh -c '<< other code >>; [ "$0" != "" ] && exit "$0"; exit "$1"' "$?" "$status"
또는 더미/패드 매개변수를 추가할 수 있습니다.
sh -c '<< other code >>; [ "$1" != "" ] && exit "$1"; exit "$2"' foo "$?" "$status"
그러면 테스트는 [ ! -z "$0" ]
(또는 "$1"
)로 변경될 수 있습니다. zsh 또는 Fish에서 작동하는지 모르겠습니다. 내가 익숙한 모든 쉘은 구문 분석되는 명령을 평가하고 $?
명령에 대한 인수로 전달합니다. 쉘은 이를 마지막 두 위치 인수에 할당합니다. "다른 코드"가 완료되면 쉘은 값을 가져온 위치 매개변수를 확인하여 비어 있는지 또는 널이 아닌지 확인하고 적절한 위치 매개변수 값으로 종료합니다.$status
sh -c
sh
$?
환경 쉘이 종료 상태를 저장하기 위해 $?
또는 이외의 것을 사용하는 경우 이 작업은 실패합니다. $status
쉘이 $?
설정(비어 있지 않음)을 허용하는 경우 $?
종료 상태가 아니거나 잘못된 문자 시퀀스인 경우에도 실패하므로 전체 명령이 구문 오류로 거부됩니다.
답변2
펄 사용:
perl -e '$a=shift; `<< other code >>`; exit $a' $? # Fails in csh
편집하다이는 csh에서도 작동합니다(그리고 zsh, tcsh, sh, pdksh, ksh93 - Fish에서는 작동하지 않음).
perl -e '$a=shift; `<< other code >>`; $a=~s/h// and exit $a; exit shift' "$?h" "$status"