[-n]이 [-n“”]처럼 거짓이 아닌 이유는 무엇입니까?


20

내 질문은이 코드에서 생성 된 반환 값에 관한 것입니다.

if [ -n ]; then echo "true"; else echo "false"; fi

이 인쇄 true됩니다.

다음을 사용하여 보완 테스트를 수행 [ -z ]합니다 true.

if [ -z ]; then echo "true"; else  echo "false"; fi

위의 코드에서 [ -n ]테스트에서 전달되지 않은 문자열 값이 null이 아닌 것으로 가정하는 이유는 무엇입니까?

아래 코드가 인쇄 false됩니다. 전달 된 문자열 값이 널이고 길이가 0이므로 예상됩니다.

if [ -n "" ]; then echo "true"; else  echo "false"; fi

답변:


14

[X는] 동일하다 [ -nX] 하더라도 의 X 로 시작 -제공 더 피연산자 없다.

$ [ -o ] ; echo $?
0
$ [ -eq ] ; echo $?
0
$ [ -n -o ] ; echo $?
0
$ [ -n -eq ] ; echo $?
0

4
역사적으로 [ -t ]stdout이 터미널인지 (단기 [ -t 1 ]) 인지 테스트 중이며 일부 쉘은 여전히 ​​수행하고 있습니다 ( 문자 그대로 의 경우 ksh93에만 -t) . [ -n "$var" ]보다 사용하는 것이 좋습니다 [ "$var" ]. 그것은 여전히 오래된에 실패했지만 test값의 구현 $var같은 =경우에, [ "" != "$var" ]또는 [ "x$var" != x ]또는 case $x in "")...더 좋을 수 있습니다.
Stéphane Chazelas

3
흥미로운 선택입니다 -o. 같은 일부 쉘에서 bash, -o단항 (옵션이 설정된 경우 테스트)와 이진 (또는) 연산자 모두는 일이 같은입니다 [ ! -o monitor ]모호하다. monitor옵션이 설정되지 않았거나 비어 있지 않은 문자열 !인지 테스트 중 monitor입니까? POSIX 규칙에 따라 후자가 결정됩니다 (와 다릅니다 [[ ! -o monitor ]]).
Stéphane Chazelas

30

[ -n ]-n테스트를 사용하지 않습니다 .

-n에는 [ -n ]전혀 검사하지 않습니다. [와 사이에 하나의 인수 만있는 ]경우 해당 인수는 비어 있는지 확인하기 위해 테스트 된 문자열입니다. 해당 문자열에 Leading -이 있더라도 테스트가 아닌 피연산자로 해석됩니다. 문자열이 때문에 -n비어 있지 - 두 개의 문자를 포함 -하고 n, 하지 제로 characters-- [ -n ]평가하여 true로.

으로 이그나시오 바스케스 - 에이 브람스는 말한다 , 어디 string하나의 인수는 테스트가 수행입니다 string에서 테스트하여 수행과 동일합니다 . 일이 발생 하면 특별한 일이 발생하지 않습니다. 에서 두 번째 에 단순히 문자열은 공허함 테스트가.[ string ][ -n string ]string-n-n[ -n ]-n[ -n -n ]

[and 사이에 하나의 인수 만있는 ]경우 해당 인수는 테스트와 동일하게 이름이 지정 되더라도 항상 비어 있지 않은지 테스트 할 문자열입니다. 마찬가지로,이 둘 개 사이에 인수 때 [와는 ]그 중 첫 번째가 -n, 두 번째는이 시험과 동일한 이름이 될 일이 있더라도, 항상 nonemptiness 테스트 할 문자열입니다. 그 이유는 and 와 after [사이의 단일 인수 가 문자열 피연산자 임을 주장 하기 때문 입니다.[]-n

테스트를 [ -n ]사용하지 않는 것과 같은 이유로 -n테스트를 [ -z ]사용하지 마십시오 -z.


당신은에 대해 자세히 배울 수 [있는을 bash그에 대한 도움말을 검사하여. 그것은 쉘 내장입니다 :

$ type [
[ is a shell builtin

따라서 help [도움을 얻기 위해 실행할 수 있습니다 .

$ help [
[: [ arg... ]
    Evaluate conditional expression.

    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.

지원되는 테스트 및 작동 방식을 포함한 자세한 내용은 도움말을 참조하십시오 test. 명령을 실행하면 help test자세한 목록이 표시됩니다. 모든 것을 재현하기보다는 문자열 연산자에 대한 부분이 있습니다.

      -z STRING      True if string is empty.

      -n STRING
         STRING      True if string is not empty.

      STRING1 = STRING2
                     True if the strings are equal.
      STRING1 != STRING2
                     True if the strings are not equal.
      STRING1 < STRING2
                     True if STRING1 sorts before STRING2 lexicographically.
      STRING1 > STRING2
                     True if STRING1 sorts after STRING2 lexicographically.

통지 -n STRING및 단지 STRING문자열이 경우 그들이 테스트 : 같은 일을 STRING비어 있지 않습니다.


2
좋은 설명
Sergiy Kolodyazhnyy

1
아마도 이것은 다음과 같이 설정되지 않은 인용되지 않은 변수에 영향을 미친다는 것을 언급 할 수도 있습니다. paste.ubuntu.com/25831047
Sergiy Kolodyazhnyy

1
@ SergiyKolodyazhnyy 별도의 답변이 더 좋을 것이라고 생각합니다. 설정되지 않았거나 설정되었지만 비어 있거나 IFS공백 만 포함 된 변수 가 그렇게합니다. 0이 아닌 여러 단어를 포함하는 변수는 다른 효과를 생성하며 완전히 다른 테스트를 실행할 수 있습니다. 피연산자가 될 의도로 문자 그대로 표시되는 문자열은 공백이나 탭이 없거나 인용 된 경우에만 제대로 작동합니다. 이 주제를 접근 가능한 방식으로 다루면 대답이 훨씬 길고 복잡해집니다. 답변을 게시하기로 결정한 경우 여기에 대한 의견을 보내 주시기 바랍니다.
Eliah Kagan

@ Eliah Kagan, Ignacio Vazquez-Abrams의 답변이 내 질문에 답변했지만 답변이 더 완전하고 상세합니다.
라비 쿠마

1
난 당신이이 방법이해야하는 이유를 놓치고 생각 :하지 않을 경우 [ "$var" ]때문에 테스트로 사용할 수 결코 $var로 확장 될 수 있습니다 -n.
R ..

12

[ -n ][명령 (일명 test명령)은 명령의 에 따라 작동 하기 때문에 true 입니다. 단일 인수 만 제공하면 인수가 비어 있지 않은 문자열 인 경우 결과는 "true"입니다. "-n"은 2자가 아닌 문자열이며 비어 있지 않으므로 "true"입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.