쉘 스크립트에는 흥미로운 버그가 있습니다

쉘 스크립트에는 흥미로운 버그가 있습니다

나는 bash GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)와 Debian의 최신 대시 동작(대시 버전을 얻는 방법?)에서 이 동작을 발견했습니다.

오류는 다음과 같습니다.

/bin/echo "Silent Err 'unexpected EOF while looking for matching' Example:"

if [ 0 -eq 1 ]; then
        /bin/echo "HERE IS MISTAKE WITHOUT QUOTE IN THE END
        exit
fi

/bin/echo " BLACK HOLE "
/bin/echo " CODE WILL NEVER PROCEED "

if [ 0 -eq 1 ]; then
        /bin/echo "SECOND MISTAKE
        exit
fi
/bin/echo "normal code... will work";
/bin/echo "Good and silent exit without any notice about BLACK HOLE code..."
/bin/echo "exit."

방사:

# bash bug_as_is.sh 
Silent Err 'unexpected EOF while looking for matching' Example:
normal code... will work
Good and silent exit without any notice about BLACK HOLE code place...
exit.

if then fi오류는 첫 번째 블록이 참조될 때만 발생합니다.

# bash unbug.sh 
Silent Err 'unexpected EOF while looking for matching' Example:
 BLACK HOLE 
 CODE WILL NEVER PROCEED 
unbug.sh: line 20: unexpected EOF while looking for matching `"'
unbug.sh: line 24: syntax error: unexpected end of file

이것은 흔히 알려진 오류입니까, 아니면 제가 진짜 다이아몬드를 발견한 것입니까? (;

이 행동의 근거는 무엇입니까?

답변1

Bash에 오류가 없습니다. 코드가 제대로 작동합니다.

echobash는 문자열이 이상해 보이고 bash 코드를 포함하더라도 여러 줄 문자열을 인수로 허용합니다 .

다음은 echo여러 줄의 문자열 출력이 포함된 명령문입니다.

        /bin/echo "HERE IS MISTAKE WITHOUT QUOTE IN THE END
        exit
fi

/bin/echo " BLACK HOLE "
/bin/echo " CODE WILL NEVER PROCEED "

if [ 0 -eq 1 ]; then
        /bin/echo "SECOND MISTAKE

이를 명확히 하기 위해 긴 문자열을 "multiline string omitted". 음, 코드는 간단합니다:

/bin/echo "Silent Err 'unexpected EOF while looking for matching' Example:"

if [ 0 -eq 1 ]; then
        /bin/echo "multiline string omitted"
        exit
fi
/bin/echo "normal code... will work";
/bin/echo "Good and silent exit without any notice about BLACK HOLE code..."
/bin/echo "exit."

위의 코드는 정상적으로 작동하는 코드입니다.

답변2

"이 행동의 중추"가 무엇을 의미하는지 잘 모르겠지만, 해석하자면 다음과 같습니다.

(겉으로는) 일치하지 않는 인용 문자열은 "HERE IS MISTAKE WITHOUT QUOTE IN THE END실제로는 인용 문자열 리터럴의 시작일 뿐입니다. 문자열 리터럴은 첫 번째 문자를 넘어 확장되며 fi선행 큰따옴표 문자까지의 모든 내용을 포함합니다 "SECOND MISTAKE.

따라서 bash비록 인간의 관점에서는 부정확하더라도 전체 혼란을 분석할 수 있습니다. 1은 수치적으로 0과 같지 않기 때문에 다음 코드 /bin/echo "HERE IS MISTAKE의 전체 블록은 실행되지 않습니다. 따라서 (명백한) 문자열은 가능한 명령으로 올바르게 구문 분석되지만 실행을 시도하지 않으므로 버그 나 기타 오류가 표시되지 않습니다 .fi"SECOND MISTAKESECOND MISTAKEbashSECOND: command not found

요약하자면, 두 줄 모두에 따옴표가 없으면 bash코드가 Single 의 "true" 절로 구문 분석 되지만 if-then-fi조건은 거짓이므로 bash사람의 눈으로 오류로 간주할 수 있는 명령을 실행하려고 시도해서는 안 됩니다. 관련 구문 오류가 발생하지 않습니다.

관련 정보