다음과 같은 (무의미한) Bash 함수가 있다고 가정해 보겠습니다.
myfunc() {
ls
failfailfail
uptime
}
나는 다음과 같이 실행합니다 :
myfunc || echo "Something is wrong."
내가 원하는 것은 ls
실행되고(해야 하기 때문에) failfailfail
작동하지 않고(존재하지 않기 때문에) uptime
실행되지 않는 것입니다. 함수의 반환 값은 0이 아니며 오류 메시지가 표시됩니다. 반환 값은 실패한 명령의 정확한 종료 상태일 필요는 없으며 단지 0이 되어서는 안 됩니다.
실제로 일어나는 일은 출력을 얻은 ls
다음 "-bash:failfailfail: command not find", 그리고 "-bash:failfailfail: command not find" 의 출력을 얻는 것입니다 uptime
. 실패한 종료 상태가 먹혀서 오류 메시지가 표시되지 않습니다.
set -e
함수 내에서나 호출 함수의 범위에서는 유용한 효과가 없습니다. 내가 원하는 방식으로 작동하게 할 수 있는 유일한 방법은 다음과 같습니다.
myfunc() {
ls || return $?
failfailfail || return $?
uptime || return $?
}
그러나 이것은 매우 반복적이고 추악해 보입니다. 이거 청소하는 다른 방법 없을까요?
답변1
에서 가 set -e
없으면 failfailfail
전체 스크립트(또는 함수가 하위 쉘에서 실행되는 경우 하위 쉘)가 종료됩니다.
함수에서 셸 상태를 수정할 필요가 없으면 하위 셸에서 실행할 수 있습니다.
myfunc() (
set -e
ls
failfailfail
uptime
)
Bash의 또 다른 방법은 다음과 같습니다.ERR
덫구현하다 return
. 로컬 설정으로 만들려면 예전 트랩 값을 복원해야 하는데, 이게 좀 번거롭습니다.
myfunc() {
local old_ERR_trap=$(trap -p ERR)
if [[ -z $old_ERR_trap ]]; then old_ERR_trap="trap - ERR"; fi
trap 'local ret=$?; eval "$old_ERR_trap"; return $ret' ERR
ls
failfailfail
uptime
}
답변2
더 간단하게 만드는 유일한 방법은 모든 것을 하나의 명령으로 결합하는 것이지만 이로 인해 이전 버전보다 스크립트를 유지 관리하기가 더 어려워집니다.
myfunc() {
ls && failfailfail && uptime || return $?
}
답변3
간단한 명령이라는 점을 고려하면 다음과 같이 할 수 있습니다.
myfunc() {
ls &&
failfailfail &&
uptime ||
return $?
}
답변4
때로는 그러한 일을 처리할 수 있는 Makefile에 내용을 넣는 것이 더 나을 때도 있습니다.
#!/bin/bash
myfunc() { # watch out for tabs!
make -f - <<!
default:
ls -d
failfailfail
uptime
!
}