왜 'test -z ='가 오류가 아닌가?

왜 'test -z ='가 오류가 아닌가?

나는 다음과 같은 책을 가지고 있습니다.

"...예를 들어, 쉘 변수 기호에 등호가 포함되어 있는 경우,

길이가 0인지 테스트하려고 하면 어떤 일이 발생하는지 확인하세요.

$ echo $symbol
= 
$ test -z "$symbol" 
sh: test: argument expected 

= 연산자는 -z 연산자보다 우선순위가 높습니다..."

하지만 Ubuntu(가상 머신에서 실행)에서 시도해 보면 다음과 같습니다.

jackson@jackson-VirtualBox:/$ symbol="="
jackson@jackson-VirtualBox:/$ echo $symbol 
=
jackson@jackson-VirtualBox:/$ test -z "$symbol"
jackson@jackson-VirtualBox:/$

테스트 명령 결과가 왜 나오지 않습니까 sh: test:argument expected?

책에 오류가 있나요?

답변1

명령 test에는 인수가 연산자인지 피연산자인지 알려주지 않습니다. 예를 들어, 쉘 코드는 매개변수를 사용하고 symbol='='; test -z "$symbol"명령을 호출합니다. 연산자인지, 해당 연산자의 피연산자인지 여부를 결정하는 것은 명령에 달려 있습니다.test-z=test-z=

대부분의 경우 문법적으로 올바른 해석은 최대 하나입니다. 예를 들어 단항 후위 연산자가 없으므로 두 인수를 구문 분석하는 유일한 방법은 첫 번째 인수가 단항 접두사 연산자이고 두 번째 인수가 피연산자인 경우입니다. 따라서 이는 (is-string-empty) 연산자를 string 에 test -z =적용한다는 의미일 뿐입니다 .-z=

세 개 이상의 매개변수가 있으면 일부 극단적인 경우가 불분명해집니다. 예를 들어, 단순 문자열 합계 또는 괄호 안의 단순 문자열에 연산자를 적용 test '(' -a ')'할 수 있습니다 . (다른 결과를 제공하는 세 가지 인수가 포함된 모호한 구문 분석은 생각할 수 없습니다.)-a()-a

이 명령의 이전 구현에는 test짧고 모호하지 않은 경우를 허용하지 않는 버그가 있는 구문 분석기가 있었습니다 -z =. 예를 들어 구문 분석기는 =두 번째 위치가 이항 연산자라고 판단한 다음 연산자에 올바른 피연산자가 없음을 깨달았습니다.Sven Mascheck의 Bourne 쉘 페이지문제가 있는 역사적 구현을 ​​나열합니다 test -a =. 여기에는 Bourne 구현과 ksh의 고대 버전이 포함됩니다.

모든 최신 구현은 2~3개의 유효한 인수가 주어지면 예상한 대로 작동합니다. 이것(그리고 그 이상)은 다음에 의해 주도됩니다.POSIX.

이 명령은 최종 매개변수로 a가 필요하다는 점을 제외하면 동일한 명령이기 때문에 [동일한 결함이 있습니다 .test]

일부 최신 쉘(ksh, bash, zsh)에서 사용 가능한 쉘 구문은 [[ … ]]쉘 내부에서 다르게 구문 분석되므로 동일한 문제가 없습니다. 는 문자열에 적용되는 연산자 [[ -z "$symbol" ]]로 구문 분석됩니다 . 값이 등호인 경우에도 해당 단어는 명령에 문자 그대로 표시되지 않으므로 연산자를 참조할 수 없습니다 .-zsymbol==

test -z "$symbol"공급업체에서 아직 지원하지 않는(또는 일부 희귀한 틈새 산업에서 어떤 형태로든 여전히 지원되는) 고대 시스템을 사용하지 않는 한, 현실 세계에서 막히는 쉘을 만나지 않을 것입니다 . 책에서 이에 대해 언급하는 경우에는 더 나은 리소스를 사용하는 것이 좋습니다. 더 좋은 책은 제3세계 국가에서는 엄청나게 비쌀 수 있지만 인터넷에는 무료로 제공되는 것들이 많이 있으며 그중 일부는 실제로 좋은 책입니다.

관련 정보