|| 조건부 실행 블록 및 괄호 관련 문제

|| 조건부 실행 블록 및 괄호 관련 문제

그래서 이것은 간단해야 합니다. 스크립트 상단에서 조건을 테스트하고 조건이 실패하면 전체 스크립트를 종료하려고 하며 종료 시 두 개의 문을 실행하고 싶습니다. 두 번째 문 없이 단독으로 exit작동하지만 두 번째 문을 어떻게 추가하더라도 완전히 종료할 수는 없습니다. 암시적 그루밍 규칙은 이 모든 항목이 한 줄에 있어야 한다는 것입니다. 나는 스크립트에 대한 이 한 줄 변경이 예상대로 작동하지 않을 때 이것을 발견했습니다. 스크립트는 계속됩니다.

먼저 무엇인지 보여드리겠습니다.하다일하다. $USER 변수가 "x"가 아니면 다음 줄이 완전히 종료되므로 괜찮습니다. 터미널 창에 이 줄을 입력하면 해당 터미널 창이 닫히고(사용자 ID가 실제로 "x"가 아닌 한) 실제로 최상위 수준 종료를 수행하기 때문에 이것이 작동한다는 것을 알고 있습니다.

[ $USER = 'x' ] || exit 1

그래서 내가 원하는 대로 괜찮습니다. 하지만 종료하기 전에 메시지를 에코하려는 경우, 에코를 추가하려고 하면 종료가 더 이상 발생하지 않거나 오히려 "다른 방식"으로 작동하는 것 같습니다.” bash 함수 컨텍스트 같은 일이 발생합니다. 다음 줄은아니요터미널을 닫으세요. 짜증나네요.

[ $USER = 'x' ] || (echo "Time to bail" ; exit 1)

세미콜론이 메아리에 먹혔을 수도 있다고 생각했는데 아니 출구에 맞은 것 같습니다. 내가 어떻게 알아? 위의 코드를 변경하고 echo $? 위에 표시된 "1"에 입력한 값이 표시됩니다. 물론 닫고 싶은 터미널 창에서 값을 보는데 닫히지 않습니다.

다음 변형은 echo와 두 번째 명령문을 실행하는 두 번째 방법도 보여 주지만,exit를 사용할 때 똑같은 동작이 다시 발생합니다.

[ $USER = 'x' ] || (echo "Time to bail" && exit 1)

여기 누군가가 이것을 이상할 뿐만 아니라 합리적으로 보이게 만들 수 있기를 바랍니다.

그렇다면 한 줄로 불가능합니까?

( :)bash --versionGNU bash, version 4.3.30(1)-release

답변1

당신이 찾고있는 것은 이것입니다 :

[ "$USER" = "x" ] || { echo "Time to bail"; exit 1; }

{ list; }명령문은 현재 쉘 컨텍스트에서 주어진 목록의 명령을 실행합니다. 기호와 달리 하위 쉘이 생성되지 않습니다 ( list ). 괄호 사이의 호출은 exit상위 쉘 자체가 아닌 하위 쉘을 종료합니다.


귀하의 질문에 포함된 하나 이상의 if 문의 예는 구문상 정확합니다. 이 동작을 재현할 수 없습니다. 줄 수는 중요하지 않습니다. if 문은 본문에서 하위 쉘을 시작하지 않습니다.


$USER참고: 변수가 비어 있으면 구문이 확장되어 아무런 효과가 없기 때문에 조건의 변수에 큰따옴표를 추가했습니다 [ = "x" ]. 큰따옴표를 사용하면 [ "" = "x" ].

답변2

팁을 주신 @mikeserv에게 감사드립니다. 대답은 매우 간단하며 괄호가 매우 특정한 종류의 그룹화를 나타낸다는 점을 인식하는 것이 중요합니다. 괄호는 하위 쉘을 생성하므로 소위 "최상위" 종료가 누락된 것으로 보입니다.

완전한 설명은여기, 주요 발췌 내용은 다음과 같습니다.

중괄호 사이에 명령 목록을 배치하면 하위 쉘 환경이 생성됩니다... 중괄호 사이에 명령 목록을 배치하면 해당 목록이 현재 쉘 컨텍스트에서 실행됩니다.

그러나 여기서 약간 불쾌한 점은 두 가지가 완전히 상호 교환 가능하지 않다는 것입니다. 중괄호는 마지막 중괄호 앞에 세미콜론이 필요한 반면 괄호는 그렇지 않습니다. 내가 따르는 구문은 세미콜론을 제거하고 "&&" 형식을 사용하려고 시도합니다.

[ $USER == 'x' ] || { echo "보석 시간" && 종료 1 ;

전체적으로 괄호는 중괄호보다 보기에 좋으며 중괄호에는 한 줄이 한 줄처럼 보이지 않도록 세미콜론이 필요합니다.

관련 정보