[bash] Bash 스크립트에서 특정 조건이 발생하면 어떻게 전체 스크립트를 종료 할 수 있습니까?
Bash에서 스크립트를 작성하여 일부 코드를 테스트하고 있습니다. 그러나 코드 컴파일이 처음에 실패하면 테스트를 실행하는 것이 어리석은 것처럼 보입니다.이 경우 테스트를 중단합니다.
전체 스크립트를 while 루프 안에 래핑하지 않고 나누기를 사용하지 않고도이 작업을 수행 할 수 있습니까? 던 던 던 고토 같은 것 ?
답변
답변
set -e 사용
#!/bin/bash
set -e
/bin/command-that-fails
/bin/command-that-fails2
스크립트는 실패한 첫 번째 줄 이후에 종료됩니다 (0이 아닌 종료 코드를 반환 함). 이 경우 command-that-fails2 가 실행되지 않습니다.
모든 단일 명령의 반환 상태를 확인하면 스크립트는 다음과 같습니다.
#!/bin/bash
# I'm assuming you're using make
cd /project-dir
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
cd /project-dir2
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
set -e를 사용하면 다음과 같습니다.
#!/bin/bash
set -e
cd /project-dir
make
cd /project-dir2
make
실패한 명령은 전체 스크립트가 실패하고 $?로 확인할 수있는 종료 상태를 반환합니다 . . 스크립트가 너무 길거나 많은 것들을 만들고 있다면 어디에서나 리턴 상태 확인을 추가하면 꽤 추악해질 것입니다.
답변
한 SysOps 사람이 나에게 Three-Fingered Claw 기술을 가르쳐주었습니다.
yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
이 기능은 * NIX OS 및 쉘 풍미에 강합니다. 스크립트 시작 부분 (bash 또는 기타)에 배치하십시오.try()
문장과 코드를 넣으십시오.
설명
( 비행 양 댓글을 기반으로 함 ).
yell
: 스크립트 이름과 모든 인수를 다음에 인쇄하십시오stderr
.$0
스크립트의 경로입니다.$*
모든 주장입니다.>&2
>
stdout을 & pipe로 리디렉션2
하는 것을 의미합니다 . 파이프1
stdout
자체 가 될 것입니다.
die
와 동일yell
하지만 0 이 아닌 종료 상태로 종료 됩니다. 이는 “실패”를 의미합니다.try
||
(booleanOR
)을 사용하는데 , 왼쪽이 실패한 경우에만 오른쪽을 평가합니다.$@
다시 모든 인수이지만 다릅니다 .
답변
로 스크립트를 호출하는 경우 스크립트 종료 상태가 될 위치 를 source
사용할 수 있습니다 (오류 또는 false에 0이 아닌 값 사용). 그러나 실행 가능한 스크립트를 호출하면 (예 : 파일 이름으로 직접) return 문에 문제가 발생합니다 ( “return : 함수 또는 소스 스크립트에서`return ‘만 할 수 있습니다”라는 오류 메시지).return <x>
<x>
경우 exit <x>
대신 사용되는 스크립트가 호출 될 때 source
,이 스크립트를 시작 쉘을 종료 될 것이다, 그러나 예상대로 실행 스크립트는 그냥 종료됩니다.
동일한 스크립트에서 두 경우 모두를 처리하기 위해
return <x> 2> /dev/null || exit <x>
이것은 어떤 호출이 적합한 지 처리합니다. 스크립트의 최상위 레벨에서이 문장을 사용한다고 가정합니다. 함수 내에서 스크립트를 직접 종료하지 않는 것이 좋습니다.
참고 : <x>
숫자 일뿐입니다.
답변
나는 종종 오류를 처리하기 위해 run ()이라는 함수를 포함합니다. 내가 만들고자하는 모든 호출은이 함수로 전달되므로 오류가 발생하면 전체 스크립트가 종료됩니다. set -e 솔루션에 비해이 방법의 장점은 줄이 실패 할 때 스크립트가 자동으로 종료되지 않고 문제가 무엇인지 알려줄 수 있다는 것입니다. 다음 예제에서는 스크립트가 false를 호출 할 때 종료되므로 3 번째 행이 실행되지 않습니다.
function run() {
cmd_output=$(eval $1)
return_value=$?
if [ $return_value != 0 ]; then
echo "Command $1 failed"
exit -1
else
echo "output: $cmd_output"
echo "Command succeeded."
fi
return $return_value
}
run "date"
run "false"
run "date"
답변
구성 대신 단락 평가를if
활용할 수 있습니다 .
#!/usr/bin/env bash
echo $[1+1]
echo $[2/0] # division by 0 but execution of script proceeds
echo $[3+1]
(echo $[4/0]) || exit $? # script halted with code 1 returned from `echo`
echo $[5+1]
대체 연산자의 우선 순위로 인해 필요한 괄호 쌍에 유의하십시오. $?
가장 최근에 호출 된 명령의 코드를 종료하도록 설정된 특수 변수입니다.
답변
나는 같은 질문을 가지고 있지만 중복 될 수 있기 때문에 요청할 수 없습니다.
스크립트가 조금 더 복잡하면 exit를 사용하여 허용 된 답변이 작동하지 않습니다. 백그라운드 프로세스를 사용하여 조건을 확인하는 경우 exit는 하위 셸에서 실행될 때만 해당 프로세스를 종료합니다. 스크립트를 죽이려면 명시 적으로 죽여야합니다 (적어도 내가 아는 유일한 방법입니다).
수행 방법에 대한 간단한 스크립트는 다음과 같습니다.
#!/bin/bash
boom() {
while true; do sleep 1.2; echo boom; done
}
f() {
echo Hello
N=0
while
((N++ <10))
do
sleep 1
echo $N
# ((N > 5)) && exit 4 # does not work
((N > 5)) && { kill -9 $$; exit 5; } # works
done
}
boom &
f &
while true; do sleep 0.5; echo beep; done
이것은 더 나은 대답이지만 여전히 불완전합니다 . 붐 부분을 제거하는 방법을 모르겠습니다 .