bash - if 문의 괄호는 어떤 역할을 합니까? [복사]

bash - if 문의 괄호는 어떤 역할을 합니까? [복사]

아마도 이것은 bash에만 적용되는 것은 아니지만 if 문에서 괄호의 역할에 대해 혼란스럽습니다. 최대다음과 같은 형식이 있는 것 같습니다.

if [ expression ]; then
    #do stuff
fi

그러나 그것이 항상 나에게 효과가 있는 것은 아닙니다. 예를 들어 다음 스크립트가 있습니다 test.sh.

#!/bin/bash

flag=False
if ! $flag; then
    echo "No brackets: Flag is $flag"
fi
if [ ! $flag ]; then
    echo "With brackets: Flag is $flag"
fi
echo "The end."

어느 인쇄

$ ./test.sh
No brackets: Flag is False
The end.

따라서 괄호를 사용하는 명령문은 무시되거나 False로 평가됩니다. 왜 이런 일이 발생합니까? 괄호는 무엇을 하는가?

이중 괄호도 본 적이 있어요. 그것들은 어떻게 사용되나요?

--

편집: 중복된 질문이 있다고 주장함(이것그리고이것)는 이 질문의 작은 부분에만 답변합니다. 괄호로 묶은 구문이 실패하는 이유(제 생각에는 test ! false로 평가되어야 함 )와 괄호 안의 구문이 성공하는 이유 가 여전히 불분명합니다 true(비록 @ilkkachu가 주석에서 언급했듯이 실제로도 실패해야 하는 것처럼 보입니까?) .

답변1

대소문자를 구분하지 않는 파일 시스템(예: macOS)을 제외한 모든 Unix에서 다음 명령문 if

if ! $flag; then
    echo "No brackets: Flag is $flag"
fi

출력을 생성합니다

bash: False: command not found
No brackets: Flag is False

macOS에서는 파일 시스템이 대소문자를 구분하지 않으므로 False명령이 표준(외부) 명령과 동일하므로 이 오류가 생성되지 않습니다.false

두 경우 모두 테스트가 ! $flag정확하므로(그러나 다른 이유로 인해) 텍스트가 인쇄됩니다. 대부분의 Unices에서는 명령을 ! $flag실행하고 False실패하며 실패가 무효화되므로 true입니다. macOS에서는 false부정을 의미하는 false를 반환하는 외부 유틸리티를 실행합니다.

두 번째 if진술은,

if [ ! $flag ]; then
    echo "With brackets: Flag is $flag"
fi

모든 Unix에서 동일한 방식으로 작동합니다. 두 개의 인수 및 를 사용하여 유틸리티를 호출합니다 [. 이는 유틸리티와 동일합니다 test(단 [마지막 피연산자와 일치해야 함). 기본적으로 문자열 인수의 길이가 0이 아닌 경우(길이가 0이 아닌 경우) 참 값이 반환되지만 이는 false를 반환함으로써 무효화되고 실행되지 않습니다.]!Falsetest!testecho

-n명확성을 위해 테스트를 사용하여 비어 있지 않은 문자열을 테스트하는 것이 좋습니다 .

if [ -n "$flag" ]; then ...

또는 -z빈 문자열을 테스트합니다.

if [ -z "$flag" ]; then ...

변수 확장에 대한 참조는 $flag파일 이름 와일드카드 패턴이 아닌 단일 단어에 대한 확장이기 때문에 이 특정 코드 부분에서는 중요하지 않습니다. 그러나 일반적으로 변수 확장은 단어 분리 및 파일 이름 글로빙을 방지하기 위해 큰따옴표로 묶어야 합니다.

[vs.에 대한 논의는 [[다음을 참조하세요.

관련된:

답변2

정확한 대답은 조금 복잡합니다. 궁극적으로 단어는 false명령이자 문자열(문맥에 따라 다름)이라는 점을 이해하세요.

자세한 설명:

문자열부터 시작해보자A_Non_Existing_Command.

str=A_Non_Existing_Command

그래서 (일반적으로 변수 확장을 인용해 주세요.)

$ if $str; then echo yes; else echo no; fi
bash: A_Non_Existing_Command: command not found
no

인쇄됩니다아니요, 실행된 명령이 실패하고(존재하지 않음) else 부분이 실행되기 때문입니다. 물론 오류 메시지도 있습니다(자세한 내용은 나중에 설명).

그러나 test 명령 test또는 [( help testread inside bash)는 다음 사항을 테스트합니다.

대괄호 사이의 문자열 길이가 0이 아닙니다.

그래서:

$ if [ "$str" ]; then echo yes; else echo no; fi
yes

yes를 인쇄합니다(문자열의 문자 수가 0이 아니기 때문입니다(보통 바이트).) 문자열이 존재하지 않는 명령의 이름이기도 한다는 것은 중요하지 않습니다. 이 경우 변수의 값은 문자열로 해석(평가)됩니다.

물론, 부정적인 테스트는 no를 출력할 것입니다:

$ if [ ! "$str" ]; then echo yes; else echo no; fi
no

이는 와 정확히 같습니다 [ -z "$str" ].

이제 str내용을 다음으로 변경 False하고 동일한 명령을 실행합니다.

 $ str=false
 $ if     "$str"  ; then echo yes; else echo no; fi
 no

 $ if [   "$str" ]; then echo yes; else echo no; fi
 yes

 $ if [ ! "$str" ]; then echo yes; else echo no; fi
 no

동일한 결과(오류 없음)가 나온다면 str=False아마도 대소문자를 구분하지 않는 파일 시스템이 있는 시스템을 사용하고 있기 때문일 것입니다(False를 검색하면 오류 없이 false가 검색됩니다).

관련 정보