조건문에서 스크립트를 종료하려면 어떻게합니까?


50

사용자가 루트가 아닌 경우 종료하려는 bash 스크립트를 작성 중입니다. 조건부는 제대로 작동하지만 스크립트가 종료되지 않습니다.

[[ `id -u` == 0 ]] || (echo "Must be root to run script"; exit)

&&대신에 사용하려고 ;했지만 작동하지 않습니다.

답변:


50

당신은 이런 식으로 할 수 있습니다 :

[[ $(id -u) -eq 0 ]] || { echo >&2 "Must be root to run script"; exit 1; }

(첫 번째 명령문에서 산술 이진 연산자를 사용하는 "일반"조건식) 또는

(( $(id -u) == 0 )) || { echo >&2 "Must be root to run script"; exit 1; }

(첫 번째 테스트의 산술 평가).

변경 ()-> {}-중괄호 는 서브 쉘을 생성 하지 않습니다 . ( man bash"서브 쉘"을 검색하십시오 .)


1
exit 1문제가 발생한 상위 프로세스를 이해하려면 0이 아닌 다른 코드로 종료하십시오 .
SamK

1
[[숫자 비교에는 사용 하지 말고을 사용하십시오 ((.
Chris Down

1
@ChrisDown 대신을 [[사용 -eq하는 한 괜찮습니다 ==.
Let_Me_Be

조건부 문제를 해결하고 산술 버전 @ChrisDown을 추가했습니다.
Mat

2
@ 매트 그건 그렇고, 당신은 그것을 줄일 수 있습니다(( EUID )) && ...
크리스 다운

21

이러한 명령 주위의 괄호는 서브 쉘을 작성합니다 . 서브 쉘은 "스크립트를 실행하려면 루트 여야합니다"를 에코 한 다음 서브 쉘 에 종료 명령을 내립니다 (명령이 더 이상 없기 때문에 이미 종료 했음 ). 그것을 해결하는 가장 쉬운 방법은 아마도 if:

if [[ `id -u` != 0 ]]; then
    echo "Must be root to run script"
    exit
fi

따라서 하나의 라이너로 이것을 할 수있는 방법이 없습니까?
개렛 홀

1
당신의 논리는 거꾸로입니다. 귀하의 예제에서, 만약 id -u == 0, 당신이 것을 의미하는 있는 루트. 당신은 원합니다 [[ $(id -u) != 0 ]]; then.
팀 케네디

4
하나의 라이너가 있어야하는 경우 크기에 대해 시도하십시오. [ "$UID" != 0 ] && echo 'You have to be root.' && exit 1;또한 $UID프로세스 생성을 저장하는을 참고하십시오 . 당신도 좋아할 것 같아요 $EUID.
janmoesen

1
@janmoesen, 좋은 지적. 그리고 숫자 값을 가진 변수가 있습니다 : ((UID)) && echo 'You have to be root.' && exit 1.
manatwork

3
@janmoesen : 이러한 역 논리를 사용하면 스크립트가 set -e중단 될 수 있습니다 . 그 문제에 대한 한 가지 해결책은 [ "$UID" != 0 ] && echo 'You have to be root.' && exit 1 || true입니다.
sam hocevar

2

bash는 :

[ $UID -ne 0 ] && echo "Must be root to run script" && exit 1

실패하면 종료되지 echo않습니다 (예 : stdout이 쓰기 가능하지 않기 때문에).
Stéphane Chazelas

1

주변 브래킷 ||&&이들로 필요하지 않습니다 마우스 오른쪽 연관됩니다. 다음 두 표현식은 동일합니다.

expr1 || expr2 && expr3
expr1 || { expr2 && expr3 }

따라서 true &&대신에 ;잘 작동 echo합니다.

[[ $(id -u) == 0 ]] || echo "Must be root to run script" && exit 1

1
당신이 말한 모든 것이 정확하지만 expr2의 반환 값에 의존하기 때문에 이것은 배우기 나쁜 패턴입니다. echo가 항상 0 종료 상태를 반환한다고 확신합니까? 문장을 중괄호와 세미콜론으로 그룹화하는 것이 훨씬 좋습니다. 이것은 BashPitfalls에 자체 항목이있는 일반적인 함정입니다 : mywiki.wooledge.org/BashPitfalls#cmd1_.26.26_cmd2_.7C.7C_cmd3
Flimm

1
@Flimm : 나는 그것이 나쁜 패턴이라는 것에 동의하지 않습니다. 분명히, 사용은 대소 문자에 따라 다르며 얻을 수있는 반환 값에 대한 지식에 달려 있습니다. 이 경우 echo가 99.999 %의 시간을 0으로 리턴하고, 쓰기 오류 (0을 리턴하지 않는 유일한 경우)에서 스톰 핑하면이 expr보다 더 큰 문제점이 있습니다. 반환 값을 생성하는 경우도 있으므로 아니요. "나쁜 패턴"이 아닙니다.
ata

Wiki에서 말하는 것처럼 C 평가를 이해하려면 반드시 사용해야한다고 덧붙입니다. 어쨌든 약간의 테스트로 모호성을 제거해야합니다.
ata

0

이것은 bash에서 도움이 될 수 있습니다.

[oracle@rac1 ~]$ which bash
/bin/bash
[oracle@rac1 ~]$ cat test1.sh
if [ `id -u` != 0 ]
then
echo "Must be root to run the script
 "
exit
fi

3
이것은 이미 답변되어 수락되었습니다. 또한 귀하의 답변은 이미 게시 된 내용과 거의 동일합니다.
maulinglawns

@maulinglawns, 그 대답은 다른 것들과 달리 모든 Bourne과 같은 쉘에 이식 할 수 있다는 장점이 있습니다 (오류가 stderr에서 출력되고 종료 상태가 0이 아니고 명령 대체가 인용되었지만 )
스테판 Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.