아마도 이것은 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를 반환함으로써 무효화되고 실행되지 않습니다.]
!
False
test
!
test
echo
-n
명확성을 위해 테스트를 사용하여 비어 있지 않은 문자열을 테스트하는 것이 좋습니다 .
if [ -n "$flag" ]; then ...
또는 -z
빈 문자열을 테스트합니다.
if [ -z "$flag" ]; then ...
변수 확장에 대한 참조는 $flag
파일 이름 와일드카드 패턴이 아닌 단일 단어에 대한 확장이기 때문에 이 특정 코드 부분에서는 중요하지 않습니다. 그러나 일반적으로 변수 확장은 단어 분리 및 파일 이름 글로빙을 방지하기 위해 큰따옴표로 묶어야 합니다.
[
vs.에 대한 논의는 [[
다음을 참조하세요.
관련된:
man test
시스템과help test
모든bash
쉘에서.- 공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?
답변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 test
read 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가 검색됩니다).