많은 명령을 실행하는 쉘 스크립트가 있습니다. 명령이 0이 아닌 종료 코드로 종료되면 쉘 스크립트를 종료하려면 어떻게합니까?
$?
모든 명령 후의 값을 테스트하십시오 . 쉬운 방법 : 넣어 set -e
또는#!/bin/bash -e
배시 스크립트의 상단에.
많은 명령을 실행하는 쉘 스크립트가 있습니다. 명령이 0이 아닌 종료 코드로 종료되면 쉘 스크립트를 종료하려면 어떻게합니까?
$?
모든 명령 후의 값을 테스트하십시오 . 쉬운 방법 : 넣어 set -e
또는#!/bin/bash -e
배시 스크립트의 상단에.
답변:
각 명령 후에는 종료 코드를 $?
변수 에서 찾을 수 있으므로 다음과 같이됩니다.
ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
$?
코드에서 파이프의 마지막 요소에 대한 리턴 코드 만 제공 하므로 파이프 된 명령에주의해야합니다 .
ls -al file.ext | sed 's/^/xx: /"
파일이 존재하지 않으면 오류 코드를 반환하지 않습니다. sed
파이프 라인 일부가 실제로 작동하기 때문에 0을 반환 함).
bash
쉘 실제로,이 경우에 도움이 될 수있는 배열을 제공되는 것 PIPESTATUS
. 이 배열에는 각 파이프 라인 구성 요소마다 하나의 요소가 있으며 ${PIPESTATUS[0]}
다음 과 같이 개별적으로 액세스 할 수 있습니다 .
pax> false | true ; echo ${PIPESTATUS[0]}
1
이것은 false
전체 파이프 라인이 아니라 명령 의 결과를 가져옵니다 . 적합하다고 생각되면 전체 목록을 처리 할 수도 있습니다.
pax> false | true | false; echo ${PIPESTATUS[*]}
1 0 1
파이프 라인에서 가장 큰 오류 코드를 얻으려면 다음과 같이 사용할 수 있습니다.
true | true | false | true | false
rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done
echo $rc
이것은 각 PIPESTATUS
요소를 차례로 통과 rc
하여 이전 rc
값 보다 큰 경우 저장합니다 .
ls -al file.ext || exit $?
([[]]는 이식 할 수 없습니다.)
[[ ]]
매우 휴대용에 bash
질문 :-) 이상하게 태그가 무엇인가, ls
에 일을하지 않는 command.com
그렇지 휴대용, 그럴듯한 I의 노하우 중 하나 그래서하지만 인수의 같은 종류의 당신 선물.
PIPESTATUS
, 즉 ( ${PIPESTATUS[0]}
첫 번째 명령 ${PIPESTATUS[1]}
또는 두 번째에 대한 ${PIPESTATUS[*]}
모든 출구 stati의 목록.
$?
직접 조사 할 필요가 거의 없다는 점을 강조해야 합니다. 일반적으로 if ls -al file.ext; then : nothing; else exit $?; fi
@MarcH와 같은 내용이 필요 ls -al file.ext || exit $?
하지만 then
or else
절이 다소 복잡하면 유지 관리가 더 쉽습니다 .
[[ $rc != 0 ]]
당신에게 줄 것이다 0: not found
또는 1: not found
오류가 발생했습니다. 로 변경해야합니다 [ $rc -ne 0 ]
. 또한 rc=$?
제거하고 방금 사용할 수 [ $? -ne 0 ]
있습니다.
$?로 작업하려면 $?부터 각 명령 후에 확인해야합니다. 각 명령이 종료 된 후 업데이트됩니다. 즉, 파이프 라인을 실행하면 파이프 라인에서 마지막 프로세스의 종료 코드 만 가져옵니다.
다른 접근 방법은 다음과 같습니다.
set -e
set -o pipefail
이것을 쉘 스크립트의 맨 위에두면 bash가 이것을 처리하는 것처럼 보입니다. 이전 포스터에서 언급했듯이 "set -e"는 간단한 명령에서 bash가 오류와 함께 종료되도록합니다. "set -o pipefail"은 파이프 라인의 모든 명령에서 bash가 오류와 함께 종료되도록합니다.
이 문제에 대한 자세한 내용은 여기 또는 여기 를 참조 하십시오 . 여기 에 내장 된 bash 매뉴얼 섹션이 있습니다.
PIPESTATUS
. 종료 코드를 어디서나 사용 하고 확인 하는 것보다 훨씬 쉽습니다 .
#!/bin/bash -e
쉘 스크립트를 시작하는 유일한 방법입니다. foo || handle_error $?
실제로 종료 상태를 조사해야하는 경우 와 같은 것을 항상 사용할 수 있습니다 .
http://cfaj.freeshell.org/shell/cus-faq-2.html#11
어떻게의 종료 코드를받을 수 있나요 cmd1
인을cmd1|cmd2
첫째, cmd1
종료 코드는 0이 아닐 수 있으며 여전히 오류를 의미하지는 않습니다. 예를 들어
cmd | head -1
종료 상태가 141 (또는 ksh93 인 269) 인 경우 SIGPIPE 신호에 의해 중단
cmd1
되었기 때문입니다.cmd
head -1
한 줄을 읽은 후 종료 입니다.
파이프 라인 요소의 종료 상태를 알려면
cmd1 | cmd2 | cmd3
ㅏ. zsh로 :
종료 코드는 pipestatus 특수 배열에 제공됩니다.
cmd1
종료 코드는 $pipestatus[1]
이고 cmd3
종료 코드는
$pipestatus[3]
이므로 $?
항상와 같습니다
$pipestatus[-1]
.
비. bash와 함께 :
종료 코드는 PIPESTATUS
특수 배열 로 제공됩니다 .
cmd1
종료 코드는 ${PIPESTATUS[0]}
이고 cmd3
종료 코드는
${PIPESTATUS[2]}
이므로 $?
항상와 같습니다
${PIPESTATUS: -1}
.
...
자세한 내용은 다음 링크를 참조하십시오 .
bash의 경우 :
# this will trap any errors or commands with non-zero exit status
# by calling function catch_errors()
trap catch_errors ERR;
#
# ... the rest of the script goes here
#
function catch_errors() {
# do whatever on errors
#
#
echo "script aborted, because of errors";
exit 0;
}
bash에서 이것은 쉽습니다. &&와 함께 묶으십시오.
command1 && command2 && command3
중첩 된 if 구문을 사용할 수도 있습니다.
if command1
then
if command2
then
do_something
else
exit
fi
else
exit
fi
if (! command)
명령에서 0이 아닌 오류 코드가 예상되는 경우 작성할 수도 있습니다 .
#
#------------------------------------------------------------------------------
# run a command on failure exit with message
# doPrintHelp: doRunCmdOrExit "$cmd"
# call by:
# set -e ; doRunCmdOrExit "$cmd" ; set +e
#------------------------------------------------------------------------------
doRunCmdOrExit(){
cmd="$@" ;
doLog "DEBUG running cmd or exit: \"$cmd\""
msg=$($cmd 2>&1)
export exit_code=$?
# if occured during the execution exit with error
error_msg="Failed to run the command:
\"$cmd\" with the output:
\"$msg\" !!!"
if [ $exit_code -ne 0 ] ; then
doLog "ERROR $msg"
doLog "FATAL $msg"
doExit "$exit_code" "$error_msg"
else
#if no errors occured just log the message
doLog "DEBUG : cmdoutput : \"$msg\""
doLog "INFO $msg"
fi
}
#eof func doRunCmdOrExit
$*
. "$@"
공백과 와일드 카드를 보존 하려면 대신 사용 하십시오.