null 문자열을 확인하고 싶다면
[ -z $mystr ]
그러나 변수가 정의되어 있는지 확인하려면 어떻게해야합니까? 아니면 Bash 스크립팅에 차이가 없습니까?
답변
Vinko 의 답변에 따르면 당신이 따르는 대답은 암시되어 있지만 (단, 명시되지 않은 경우) 단순히 철자가 아닙니다. VAR이 설정되었지만 비어 있는지 여부를 구별하려면 다음을 사용할 수 있습니다.
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
두 번째 줄의 두 테스트를 다음과 함께 하나로 결합 할 수 있습니다.
if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
그러나 Autoconf에 대한 설명서를 읽으면 용어를 ‘ -a
‘와 함께 사용하지 않는 것이 좋으며와 함께 별도의 간단한 테스트를 사용하는 것이 좋습니다 &&
. 문제가있는 시스템을 발견하지 못했습니다. 그렇다고 그들이 존재하지 않았 음을 의미하지는 않습니다 (그러나 먼 과거에 희귀하지 않았더라도 요즘에는 극히 희귀합니다).
Bash 매뉴얼에서 이들에 대한 세부 사항과 기타 관련 쉘 매개 변수 확장 , test
또는[
명령 및 조건식을 찾을 수 있습니다 .
나는 최근에 다음과 같은 질문에 대한 답을 이메일로 받았다.
두 가지 테스트를 사용하고 두 번째 테스트는 잘 이해하지만 첫 번째 테스트는 이해하지 못합니다. 더 정확하게는 변수 확장의 필요성을 이해하지 못합니다
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
이것이 동일하게 달성되지 않습니까?
if [ -z "${VAR}" ]; then echo VAR is not set at all; fi
공정한 질문-대답은 ‘아니요, 더 간단한 대안은 같은 것을하지 않습니다’입니다.
테스트 전에 이것을 작성한다고 가정 해보십시오.
VAR=
테스트에는 “VAR이 전혀 설정되어 있지 않습니다”라고 표시되지만 “VAR이 설정되었지만 값이 비어있을 수 있습니다”라는 메시지가 나타납니다. 이 스크립트를 사용해보십시오 :
(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:2 VAR is not set at all; fi
)
출력은 다음과 같습니다.
JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all
두 번째 테스트 쌍에서는 변수가 설정되지만 비어있는 값으로 설정됩니다. 이것이 ${VAR=value}
와 ${VAR:=value}
표기법 의 구별입니다 . 동감 ${VAR-value}
하고 ${VAR:-value}
,과 ${VAR+value}
및 ${VAR:+value}
등.
Gili 가 그의 대답 에서 지적한 것처럼 bash
, set -o nounset
옵션으로 실행 하면 위의 기본 대답이 실패합니다 unbound variable
. 쉽게 해결됩니다.
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
또는 ( 와 같음 ) 으로 set -o nounset
옵션을 취소 할 수 있습니다.set +u
set -u
set -o nounset
답변
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~>
-z는 정의되지 않은 변수에도 적용됩니다. 정의되지 않은 정의와 정의되지 않은 정의를 구별하려면 여기에 나열된 내용을 사용 하거나 더 명확한 설명과 함께 here을 사용 하십시오 .
가장 깨끗한 방법은이 예제와 같이 확장을 사용하는 것입니다. 모든 옵션을 얻으려면 매뉴얼의 파라미터 확장 섹션을 확인하십시오.
다른 단어 :
~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED
기본값:
~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED
물론 이들 중 하나를 다르게 사용하여 ‘기본값’대신 원하는 값을 넣고 적절한 경우 확장을 직접 사용합니다.
답변
고급 bash 스크립팅 안내서, 10.2. 매개 변수 대체 :
- $ {var + blahblah} : var가 정의 된 경우 ‘blahblah’가 표현식으로 대체되고, 그렇지 않으면 null이 대체됩니다.
- $ {var-blahblah} : var이 정의 된 경우 var 자체가 대체되고 그렇지 않은 경우 ‘blahblah’가 대체됩니다
- $ {var? blahblah} : var이 정의되어 있으면 대체되고, 그렇지 않으면 오류 메시지로 ‘blahblah’가있는 함수가 존재합니다.
변수 $ mystr의 정의 여부에 따라 프로그램 논리를 작성하려면 다음을 수행하십시오.
isdefined=0
${mystr+ export isdefined=1}
이제 isdefined = 0이면 변수가 정의되지 않은 것이고 isdefined = 1이면 변수가 정의 된 것입니다.
변수를 검사하는 이러한 방법은 위의 답변보다 우수하고 읽기 쉽고, 정의되지 않은 변수를 사용할 때 bash 쉘이 오류로 구성되어 있으면 (set -u)
스크립트가 조기에 종료됩니다.
다른 유용한 것들 :
정의되지 않은 경우 $ mystr에 기본값 7을 지정하고 그렇지 않으면 그대로 두십시오.
mystr=${mystr- 7}
변수가 정의되지 않은 경우 오류 메시지를 인쇄하고 함수를 종료하려면 다음을 수행하십시오.
: ${mystr? not defined}
$ mystr의 내용이 정의 된 경우 명령으로 실행되지 않도록 ‘:’을 사용했다는 것을 명심하십시오.
답변
테스트 요약.
[ -n "$var" ] && echo "var is set and not empty"
[ -z "$var" ] && echo "var is unset or empty"
[ "${var+x}" = "x" ] && echo "var is set" # may or may not be empty
[ -n "${var+x}" ] && echo "var is set" # may or may not be empty
[ -z "${var+x}" ] && echo "var is unset"
[ -z "${var-x}" ] && echo "var is set and empty"
답변
https://stackoverflow.com/a/9824943/14731 더 나은 답변 (더 읽기 쉽고 set -o nounset
활성화 된 답변)이 포함되어 있습니다 . 대략 다음과 같이 작동합니다.
if [ -n "${VAR-}" ]; then
echo "VAR is set and is not empty"
elif [ "${VAR+DEFINED_BUT_EMPTY}" = "DEFINED_BUT_EMPTY" ]; then
echo "VAR is set, but empty"
else
echo "VAR is not set"
fi
답변
정의되는 변수를 확인하는 명시적인 방법은 다음과 같습니다.
[ -v mystr ]
답변
또 다른 옵션 : “목록 배열 색인”확장 :
$ unset foo
$ foo=
$ echo ${!foo[*]}
0
$ foo=bar
$ echo ${!foo[*]}
0
$ foo=(bar baz)
$ echo ${!foo[*]}
0 1
이것이 빈 문자열로 확장되는 유일한 시간 foo
은 설정 되어 있지 않으므로 문자열 조건부로 확인할 수 있습니다.
$ unset foo
$ [[ ${!foo[*]} ]]; echo $?
1
$ foo=
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=bar
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=(bar baz)
$ [[ ${!foo[*]} ]]; echo $?
0
bash 버전> = 3.0에서 사용할 수 있어야합니다.