bash if 문의 다른 동작

bash if 문의 다른 동작

명령문 동작에 대해 몇 가지 테스트를 수행했지만 bash if해당 명령문이 출력되는 이유를 정확하게 이해하고 있는지 잘 모르겠습니다.

다음은 각각의 다른 명세서 출력에서 ​​제가 생각해낸 이유입니다 if. 모든 이유가 맞습니까? 나도 답을 못찾겠다행동 중 하나아래에 설명된 바와 같습니다. 배쉬 버전은 4.1.2입니다.

#!/bin/bash

set -x

# behavior 1
if [ $anything ]; then
        echo 'true 1'
fi
# result is false cause $anything will be translated by bash to an empty string, and in 'test' command, EXPRESSION omitted will be false

# behavior 2
if [ '' ];then
        echo 'true 2'
fi
# result is false cause in 'test' command, EXPRESSION omitted will be false

# behavior 3
if [ 0 ]; then
        echo 'true 3'
fi
# result is true cause 0 is a STRING and that is same with '-n STRING', since the length of string '0' is definitely nonzero, so it is true

# behavior 4
if [ ]; then
        echo 'true 4'
fi
# result is false cause in 'test' command, EXPRESSION omitted will be false

# behavior 1a
if $anything; then
        echo 'true 1a'
fi
# result is true. But I don't understand why since bash will translate $anything to an empty string, shouldn't this will result in syntax error ?

# behavior 2a
if ''; then
        echo 'true 2a'
fi
# syntax error cause 'list' is empty and command can not be found

# behavior 3a
if 0; then
        echo 'true 3a'
fi
# syntax error cause 'list' is 0 and there is no such command as 0

# behavior 4a
if ; then
        echo 'true 4a'
fi
# syntax error cause list is empty


set +x

답변1

그것은 사실로 밝혀졌습니다. 그러나 bash가 $anything을 빈 문자열로 변환하므로 구문 오류가 발생하지 않는 이유를 이해할 수 없습니다.

닫혀 있지만 쿠키는 없습니다. 다음과 같은 표현이 있습니다 $anything. if ; thenbash는 할 수 없기 때문에 오류입니다분석하다그것(그러므로:통사론실수). 거기에 명령 목록이 있을 것으로 예상하고 하나를 얻습니다 ;. 변수 확장이 발생하기 전에 구문 분석이 발생하므로 if $anything; then잘 구문 분석됩니다. 다음에는 어떻게 되나요? $anything확장, 분야 세분화 등을 수행합니다. 이로 인해 빈 명령 목록이 남게 되는데, 실제로 그렇습니다. 비교하다:

if "$anything"; then echo foo; fi
if $anything; then echo foo; fi

"$anything";빈 명령 목록 대신 와 마찬가지로 빈 문자열에서 발생하는 명령이 있습니다 if '';. 그러나 참조되지 않은 콘텐츠는 "$anything"아무 것도 확장되지 않습니다.

$anything이는 에 있는 공백 문자만 포함되거나 IFS어떤 $IFS파일과도 일치하지 않는 구분된 glob 목록이 포함되고 이 옵션이 설정된 경우에도 마찬가지입니다 nullglob.

답변2

명령문의 대괄호는 [ "$foo" ]명령의 약어입니다 test. [ "$foo" ]그리고 test "$foo"동등합니다.

반면, 단순히 공백 또는 설정되지 않은 문자열을 입력하면 true종료 코드가 반환됩니다.

unset foo; $foo; echo $?
0

비교:

unset foo ; test $foo ; echo $?
1

관련 정보