“set -o nounset”을 사용할 때 bash에서 변수가 설정되었는지 테스트


95

다음 코드는 바인딩되지 않은 변수 오류와 함께 종료됩니다. set -o명사 옵션 을 계속 사용 하면서이 문제를 해결하는 방법은 무엇입니까?

#!/bin/bash

set -o nounset

if [ ! -z ${WHATEVER} ];
 then echo "yo"
fi

echo "whatever"

답변:


98
#!/bin/bash

set -o nounset


VALUE=${WHATEVER:-}

if [ ! -z ${VALUE} ];
 then echo "yo"
fi

echo "whatever"

이 경우를 설정하지 않으면 VALUE빈 문자열 WHATEVER이됩니다. "매개 변수 확장" {parameter:-word}에서 찾아 볼 수 있는 확장을 사용하고 있습니다 man bash.


14
[! -z $ {VALUE}]; if [! -z $ {무엇이든 :-}];
Angelom 2011 년

18
:-변수가 설정되지 않았 는지 비어 있는지 확인합니다 . 설정되지 않았는지 여부 확인 하려면 -:을 사용 하십시오 VALUE=${WHATEVER-}. 또한 변수가 비어 있는지 확인하는 더 읽기 쉬운 방법 :if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
l0b0

1
또한 $WHATEVER공백 만 포함 하면 작동하지 않습니다 . 내 대답을 참조하십시오.
l0b0

10
" ! -z"대신 " " 를 사용하는 이유가 -n있습니까?
Jonathan Hartley

31

예상 한 결과를 얻으려면 변수를 인용해야합니다.

check() {
    if [ -n "${WHATEVER-}" ]
    then
        echo 'not empty'
    elif [ "${WHATEVER+defined}" = defined ]
    then
        echo 'empty but defined'
    else
        echo 'unset'
    fi
}

테스트:

$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER='   '
$ check
not empty

에 따라 제외하고 나는이 시도하고 나는이 작품을 놀랍군요 ... 모든 것이 정확 "info bash", "${WHATEVER-}"해야 ":"전과 (콜론) "-": 같은 (대시) "${WHATEVER:-}", 및 "${WHATEVER+defined}"전과 콜론이 있어야합니다 "+"(플러스) 등이 : "${WHATEVER:+defined}". 나에게는 콜론이 있든 없든 상관없이 작동합니다. 'nix의 일부 버전에서는 콜론을 포함하지 않으면 작동하지 않을 수 있으므로 추가해야합니다.
Kevin Fegan 2014 년

8
아니, -, +, :+, 그리고 :-모두 지원됩니다. 전자는 변수 유무를 검출 설정 하고, 후자가 검출되는지 여부를 설정 또는 비우 . From man bash: "콜론을 생략하면 설정되지 않은 매개 변수에 대해서만 테스트됩니다."
l0b0 2014 년

1
신경 쓰지 마세요 =). 당신이 올바른지. 어떻게 놓쳤는 지 모르겠습니다.
Kevin Fegan 2014 년

로부터 문서 : 콜론이 포함 된 경우, 두 매개 변수의 존재와 그 값이 null이 아닌 그 운영자 테스트를 다른 방법을 넣어; 콜론이 생략되면 연산자는 존재 여부 만 테스트합니다.
Acumenus 2014

8

Oneliner는 어떻습니까?

[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"

-z 비어 있거나 설정되지 않은 변수를 모두 확인합니다.


2
아니요, -z다음 매개 변수가 비어 있는지 확인합니다. -zis는 [명령 의 인수 일뿐 입니다. 변수 확장 [ -z은 무엇이든 할 수 있기 전에 발생합니다 .
고인돌

1
$ VAR이 설정되지 않은 경우 오류를 생성하지 않는다는 점에서 올바른 솔루션으로 보입니다. @dolmen이 작동하지 않을 때의 예를 제공 할 수 있습니까?
Chris Stryczynski

@dolmen은 param 확장에 대한 다양한 bash 리소스를 읽고 지나치게 복잡한 다른 답변을 찾았습니다. 따라서 "명확"은 기술적으로 정확하지만 설정되지 않은 것과 비어있는 것을 구분할 필요가없는 한 실제로는 무의미 해 보입니다. 나는 설정되지 않고 비어 있지 않고 비어 있지 않은 것을 테스트했으며 (bash 4) 매번 광고되는 내용을 거의 수행했습니다.
JL Peyret

8

가정 :

$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset

비대화 형 스크립트가 오류를 인쇄하고 변수가 null이거나 설정되지 않은 경우 종료하도록하려면 다음을 수행하십시오.

$ [[ "${HOME:?}" ]]

$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set

$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set

스크립트를 종료하지 않으려면 :

$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."

$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

당신은 사용할 수 있습니다 []대신 [[하고 ]]이상하지만, 후자는 배쉬에서 바람직하다.

위에서 콜론이 무엇을하는지 주목하십시오. 로부터 문서 :

즉, 콜론이 포함 된 경우 연산자는 두 매개 변수의 존재 여부와 그 값이 null이 아닌지 테스트합니다. 콜론이 생략되면 연산자는 존재 여부 만 테스트합니다.

-n또는에 대한 필요가 분명히 없습니다 -z.

요약하면 일반적으로 [[ "${VAR:?}" ]]. 예제에 따라 이것은 오류를 인쇄하고 변수가 null이거나 설정되지 않은 경우 종료됩니다.


4

당신이 사용할 수있는

if [[ ${WHATEVER:+$WHATEVER} ]]; then

그러나

if [[ "${WHATEVER:+isset}" == "isset" ]]; then

더 읽기 쉬울 수 있습니다.


문자열 비교는 이식성을 지원 =하지 않고 가능한 경우 대신 표준 (POSIX) 연산자 를 사용해야합니다. ==[[[
Jens

2
@Jens 질문은 bash에만 해당되며 bash에만 해당되는 내용 set -o nounset을 포함 합니다. #!/bin/bash스크립트 맨 위에을 넣으면 실제로 bash의 향상된 기능을 사용하는 것이 가장 좋습니다.
Bruno Bronosky

0

이것이 위에서 요구 한 사용 사례 와 정확히 일치 하지는 않지만 기본 동작 을 사용 nounset(또는 -u) 하려는 경우 원하는 동작 인 설명 메시지와 함께 0이 아닌 상태를 종료하는 것입니다.

해결책으로 게시 할 가치가 있다고 생각한 것을 깨닫는 데 시간이 충분히 걸렸습니다.

종료 할 때 다른 것을 에코하거나 정리를 수행하는 것뿐이라면 트랩을 사용할 수 있습니다.

:-연산자를 사용하면, 그렇지 않으면 원하는 아마.

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