bash는 조건부에서 공백을 둘러싸지 않고 같음 연산자를 어떻게 해석합니까?

bash는 조건부에서 공백을 둘러싸지 않고 같음 연산자를 어떻게 해석합니까?

다음 스크립트는 예상한 것과 다르게 동작합니다. 조건문에서 "=" 주위에 공백을 추가하면 내가 원하는 대로 작동하지만 조건문에서 실제로 무엇을 하고 있는지 생각하게 되었습니다.

#!/bin/bash
S1='foo'
S2='bar'
if [ $S1=$S2 ];
then
    echo "S1('$S1') is equal to S2('$S2')
fi
echo $S1
echo $S2

출력은 다음과 같습니다

S1('foo') is equal to S2('bar')
foo
bar

S1과 S2의 내용은 할당된 내용을 변경하지 않으므로 할당이 수행되지 않습니다.

답변1

이는 Bourne과 유사한 대부분의 쉘과 마찬가지로 Bash에서도 [사용할 수 test있는 명령이므로 내장 명령이므로 info bash [내부에서 검색하여 문서를 사용하거나 볼 수 있습니다 man bash( man builtin일부 시스템에서는 bash). 시스템 전체에도 적용됩니다 sh).

이 문서에서:

test그리고 [인수 수에 따라 일련의 규칙을 사용하여 조건식을 평가합니다.

  • 인수 0개
    표현식이 거짓입니다.
  • 1 매개변수
    매개변수가 비어 있지 않은 경우에만 표현식이 true입니다.
  • 2개의 매개변수
    [...]
  • 3개의 매개변수
    [...]

현명하게 말하자면, 명령 [대신 사용할 때 마지막(필수)은 다음 과 같습니다.test]반품하나의 인수이지만 이는 위의 숫자에 포함되지 않습니다(bash 문서에서 직접 참조). 그래도...

2매개변수 규칙은 다양한 테스트이고, 3매개변수 규칙은 일반적으로 비교입니다. 주위에 공백을 추가하면 =세 개의 매개변수를 얻게 됩니다. 하지만 그것들을 합치면,하나매개변수는 보시다시피 매개변수가 null이 아니면 true를 반환합니다.

글쎄, 기술적으로는 매개변수 확장 [ $S1=$S2 ](및 다른 곳) 에 대한 따옴표를 잊어 $S1버렸고 $S2Split+glob 의 영향을 받기 때문에 더 많은 매개변수가 [명령 에 전달될 수 있습니다. ksh와 마찬가지로 bash에서도 이는 명령 주입 취약점을 구성할 수 있습니다.

예를 들어, 분할된 부분으로 및 로 $S1정의된 경우 기본값은 Yield , , 입니다. 와일드 카드는 현재 디렉터리에 해당 파일이 있는 경우 확장되지만 그렇지 않은 경우에는 그대로 전달됩니다. bash의 내장 기능에는 명령 출력을 기반으로 인덱스를 결정하기 위해 배열 요소가 설정되고 확장되었는지 확인하는 테스트가 있습니다.S1='-v xx[$(reboot)] -o yy'$S2S2='zz'$IFS-vxx[$(reboot)]-oyy=zz[...]xx[$(reboot)]xxoxxtxx[$(reboot)][-v array[index][$(reboot)reboot

올바른 구문에서는 [ "$S1" = "$S2" ]따옴표를 잊지 않는 것도 중요합니다.

답변2

이 경우 같음 연산자는 아무 작업도 수행하지 않습니다.

표현식은 실제로 문자열 리터럴인 값이 있는 $S1=$S2실제 문자열로 평가됩니다 .S1S2foo=bar

문자열 리터럴이 비어 있지 않으므로 명령문은

if [ "foo=bar" ];

true로 평가되고 if 문의 본문이 실행됩니다.

관련 정보