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

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

#!/bin/bash

set -o nounset

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

echo "whatever"



답변

#!/bin/bash

set -o nounset


VALUE=${WHATEVER:-}

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

echo "whatever"

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


답변

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

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


답변

Oneliner는 어떻습니까?

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

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


답변

가정 :

$ 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이거나 설정되지 않은 경우 종료됩니다.


답변

당신이 사용할 수있는

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

그러나

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

더 읽기 쉬울 수 있습니다.


답변

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

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

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

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


답변