매개변수가 빈 문자열로 설정되었는지 테스트하는 방법은 무엇입니까?

매개변수가 빈 문자열로 설정되었는지 테스트하는 방법은 무엇입니까?

매개변수가 빈 문자열인지 테스트하고 싶습니다 "".

이 매개변수가 설정되지 않으면 테스트가 실패합니다.

  1. 다음 작업이 성공하지 못한 이유는 무엇입니까?

    $ unset aa
    $ if [ ${aa}=="" ]; then echo yes; else echo no; fi
    yes
    
  2. 어떻게 해야 하나요?

답변1

(시도한) 테스트는 $aa == ""두 개의 빈 문자열을 서로 비교하는 것으로 실제 결과를 생성합니다. 이는 쉘이 설정되지 않은 변수를 빈 문자열로 확장하기 때문입니다. 주변에 공백이 없으면 ==두 문자열에 대한 테스트와 동일하므로 테스트는 항상 true입니다 ==. 이 문자열은 항상 참입니다.

대신에 bash:

$ unset aa
$ if [ -v aa ]; then echo Set; else echo Not set; fi
Not set
$ aa=""
$ if [ -v aa ]; then echo Set; else echo Not set; fi
Set

따라서 빈 문자열에 대한 완전한 테스트는 다음과 같습니다.

if [ -v aa ] && [ -z "$aa" ]; then
    echo Set but empty
fi

에서 help test:bash

-v VARVAR쉘 변수가 설정된 경우 참입니다.

또는 bash매뉴얼의 "조건식" 섹션에서:

-v varname

쉘 변수가 설정된 경우 varname(값이 할당된 경우) 참입니다.

테스트를 통해 -v변수를 테스트할 수 있습니다.이름그 가치를 보기보다는


정말로 문자열 비교를 하고 싶다면,할 수 있다다음과 같은 일을 해라

if [[ "${aa-InvalidValue}" != "InvalidValue" ]] && [ -z "$aa" ]; then
    echo Set but empty
fi

설정하지 않으면 확장자가 ${variable-value}확장됩니다.valuevariable

매우 유사한 내용이 if is unset ${variable:-value}으로 확장됩니다 .valuevariable또는 비어 있음(빈 문자열).

답변2

test, 즉 는 [연산자 주위에 공백이 필요합니다. 그렇지 않으면 foo==유효한 문자열이더라도 연산자를 포함하는 것으로 처리되기 때문입니다. 구조 [[ .. ]]는 같은 방식으로 작동합니다. (바라보다이 문제그리고배쉬 FAQ 031[차이점을 비교해보세요 [[. )

그럴 [ ${aa}=="" ]것이다언제나[ string ]와 동일하기 때문에 true입니다 [ -n string ]. 즉, 문자열이 비어 있지 않은지 테스트합니다. 여기 문자열에는 최소한 ==.

설정되지 않거나 비어 있으면 따옴표 확장이 없는 빈 변수가 사라지고 유효한 테스트가 아니기 때문에 [ ${aa} == "" ]오류가 발생합니다 . Null이 아닌 값이 있으면 False입니다 . ( 이것은 특별하기 때문에 따옴표 없이도 작동합니다 .)aa[ == foo ]aa[[ ${aa} == "" ]][[ .. ]]

물론 와 마찬가지로 설정되지 않았거나 비어 있는지 [ "${aa}" == "" ]테스트합니다 .aa[ -z "${aa}" ]


비어 있는지 테스트하기 위해 를 사용 [ "${aa+x}" ] && [ -z "$aa" ]하거나 두 가지를 교묘하게 결합할 수 있습니다.@Stéphane Chazelas의 답변:

if [ "${aa+x$aa}" = "x" ] ; then
    echo "aa is empty but set"
fi

aa(이것은 설정되지 않은 경우 빈 문자열로 확장되고 +, 설정된 경우( x$aa즉 , 비어 있는 x경우 )로 확장되기 때문에 작동합니다 aa.)

$ foo() { [ "${1+x$1}" = "x" ] && echo "set but empty" || echo "unset or non-empty"; }    
$ foo; foo ""; foo bar
unset or non-empty
set but empty
unset or non-empty

답변3

==첫째, 주변에 공간이 필요하다는 것을 알고 있다고 가정합니다 . 의 사용은 ==bash, ksh 및 zsh에서만 유효하며 가장 잘 사용됩니다 =. 또한 테스트 내에서 확장된 변수를 참조해야 합니다. 그래서 나는 그 줄이 실제로 다음과 같다고 가정합니다.

unset aa ; if [ "${aa}" = "" ]; then echo yes; else echo no; fi

이 시점에서 귀하의 질문은 다음과 같습니다.

다음 작업이 성공하지 못한 이유는 무엇입니까?

일반 unset var의 확장은 null로 설정된 일반 변수의 확장과 동일하기 때문입니다("["가 수행할 수 있는 작업 테스트에서).

I mean, "$aa" is the same value for both an unset aa or a null aa.

이것이 어떻게 작동하는지 보여주기 위해 다음 스크립트를 시도해 보십시오(이 스크립트는 sh이며 dash, bash, ksh 및/또는 zsh에서 동일하게 작동합니다).

#!/bin/sh

blanktest(){
    if [ "${aa}" = "" ]; then echo "$1 yes"; else echo "$1 no"; fi
}

unset aa; blanktest unset
unset aa; aa="";  blanktest blank
unset aa; aa="e"; blanktest value

실행되면 다음이 생성됩니다.

$ ./script
unset yes
blank yes
value no

어떻게 해야 하나요?

"대체 값 사용"이라는 매개변수 확장을 사용합니다. :

${aa+x}

변수(null 또는 값)가 설정되면 x가 생성되고, 변수가 설정되지 않으면 null이 생성됩니다.

대신 이 테스트를 사용해 보세요:

[ "x${aa}x" = "x${aa+x}" ] && echo yes || echo no

테스트 스크립트(다시 말하지만, sh 호환 가능):

#!/bin/sh

blanktest(){
    if [ "x${aa}x" = "x${aa+x}" ]; then echo "$1 yes"; else echo "$1 no"; fi
}

unset aa; blanktest unset
unset aa; aa="";  blanktest blank
unset aa; aa="e"; blanktest value

실행되면 다음과 같이 인쇄됩니다.

$ ./script
unset no
blank yes
value no

관심이 있으시면 몇 가지 가능한 변형이 있습니다.

관련 정보