[bash] Bash 셸 스크립트에 문자열이 정의되어 있지 않은지 확인하는 방법

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 +uset -uset -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에서 사용할 수 있어야합니다.