ERR 및 EXIT 트랩과 함께 set -e
( errexit
), set -u
( nounset
)를 사용할 때 이상한 동작이 관찰됩니다 . 그것들은 관련이있는 것처럼 보이므로, 하나의 질문에 넣는 것이 합리적입니다.
1) set -u
ERR 트랩을 트리거하지 않습니다
암호:
#!/bin/bash trap 'echo "ERR (rc: $?)"' ERR set -u echo ${UNSET_VAR}
- 예상 : ERR 트랩이 호출됩니다. RC! = 0
- 실제 : ERR 트랩이 호출 되지 않음 , RC == 1
- 참고 :
set -e
결과를 변경하지 않습니다
2) set -eu
EXIT 트랩에서 종료 코드 사용은 1 대신 0입니다.
암호:
#!/bin/bash trap 'echo "EXIT (rc: $?)"' EXIT set -eu echo ${UNSET_VAR}
- 예상 : EXIT 트랩이 호출되고 RC == 1
- 실제 : EXIT 트랩 호출, RC == 0
- 참고 :를 사용할 때
set +e
RC == 1입니다. EXIT 트랩은 다른 명령에서 오류가 발생하면 올바른 RC를 반환합니다. - 편집 : 이 주제 에 사용되는 Bash 버전과 관련이 있다는 흥미로운 의견 이있는 SO 게시물 이 있습니다. Bash 4.3.11로이 스 니펫을 테스트하면 RC = 1이되므로 더 좋습니다. 불행히도 현재 모든 호스트에서 Bash (3.2.51에서)를 업그레이드하는 것은 불가능하므로 다른 해결책을 찾아야합니다.
누구든지 이러한 행동 중 하나를 설명 할 수 있습니까?
이러한 주제를 검색하는 데 성공하지 못했습니다. Bash 설정 및 트랩에 대한 게시물 수가 많으면 놀랍습니다. 그러나 포럼 스레드 가 하나 있지만 결론은 다소 불만족입니다.
set -e
그리고 set -u
둘 다하기 위해 특별히 설계된 죽일 스크립팅 쉘을. 것이다 애플리케이션 실행할 수있는 조건을 사용하여 죽일 스크립팅 쉘을. 그것들을 사용 하지 않고 코드 시퀀스에 적용 할 때 그러한 조건 을 테스트 하는 것을 제외하고는 그 문제를 해결할 수 없습니다 . 따라서 기본적으로 좋은 쉘 코드를 작성하거나을 사용할 수 있습니다 set -eu
.
-u
ERR 트랩을 트리거하지 않는 이유 (오류이므로 트랩을 트리거 해서는 안 됨)에 대한 충분한 정보를 찾을 수 없거나 오류 코드가 1 대신 0이므로 둘 다 찾고 있습니다. 후자는 이미 이후 버전에서 수정 된 버그 인 것 같습니다. 그러나 쉘 평가 (매개 변수 확장)의 오류와 명령의 실제 오류가 두 가지 다른 것 같다는 것을 깨닫지 못하면 첫 번째 부분을 이해하기가 매우 어렵습니다. 솔루션의 경우, 제안한대로 -eu
필요할 때 수동으로 피하고 확인 하려고 합니다.
(set -u; : $UNSET_VAR)
과 같은 하위 셸 컨텍스트로 현지화 할 수 있습니다 . 이런 종류의 물건도 좋을 수 있습니다- &&
때때로 (set -e; mkdir dir; cd dir; touch dirfile)
드리프트를 얻는다면 많은 것을 떨어 뜨릴 수 있습니다 . 그것들은 단지 통제 된 맥락 일뿐입니다-그것들을 전역 옵션으로 설정하면 통제를 잃고 통제됩니다. 그러나 일반적으로 더 효율적인 솔루션이 있습니다.
bash
표준을 깨고 트랩을 서브 쉘에 넣기 시작 했다고 생각 합니다. 함정이 돌아 왔을 때와 같은 환경에서 함정을 실행해야하지만bash
꽤 오랫동안 그렇게하지는 않았습니다.