![매개변수가 빈 문자열로 설정되었는지 테스트하는 방법은 무엇입니까?](https://linux55.com/image/126528/%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EA%B0%80%20%EB%B9%88%20%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%20%EC%84%A4%EC%A0%95%EB%90%98%EC%97%88%EB%8A%94%EC%A7%80%20%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
매개변수가 빈 문자열인지 테스트하고 싶습니다 ""
.
이 매개변수가 설정되지 않으면 테스트가 실패합니다.
다음 작업이 성공하지 못한 이유는 무엇입니까?
$ unset aa $ if [ ${aa}=="" ]; then echo yes; else echo no; fi yes
어떻게 해야 하나요?
답변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 VAR
VAR
쉘 변수가 설정된 경우 참입니다.
또는 bash
매뉴얼의 "조건식" 섹션에서:
-v varname
쉘 변수가 설정된 경우
varname
(값이 할당된 경우) 참입니다.
테스트를 통해 -v
변수를 테스트할 수 있습니다.이름그 가치를 보기보다는
정말로 문자열 비교를 하고 싶다면,할 수 있다다음과 같은 일을 해라
if [[ "${aa-InvalidValue}" != "InvalidValue" ]] && [ -z "$aa" ]; then
echo Set but empty
fi
설정하지 않으면 확장자가 ${variable-value}
확장됩니다.value
variable
매우 유사한 내용이 if is unset ${variable:-value}
으로 확장됩니다 .value
variable
또는 비어 있음(빈 문자열).
답변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
관심이 있으시면 몇 가지 가능한 변형이 있습니다.