다음 코드는 바인딩되지 않은 변수 오류와 함께 종료됩니다. 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
.
:-
변수가 설정되지 않았 는지 비어 있는지 확인합니다 . 설정되지 않았는지 여부 만 확인 하려면 -
:을 사용 하십시오 VALUE=${WHATEVER-}
. 또한 변수가 비어 있는지 확인하는 더 읽기 쉬운 방법 :if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVER
공백 만 포함 하면 작동하지 않습니다 . 내 대답을 참조하십시오.
! -z
"대신 " " 를 사용하는 이유가 -n
있습니까?
예상 한 결과를 얻으려면 변수를 인용해야합니다.
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의 일부 버전에서는 콜론을 포함하지 않으면 작동하지 않을 수 있으므로 추가해야합니다.
-
, +
, :+
, 그리고 :-
모두 지원됩니다. 전자는 변수 유무를 검출 설정 하고, 후자가 검출되는지 여부를 설정 또는 비우 . From man bash
: "콜론을 생략하면 설정되지 않은 매개 변수에 대해서만 테스트됩니다."
Oneliner는 어떻습니까?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z
비어 있거나 설정되지 않은 변수를 모두 확인합니다.
-z
다음 매개 변수가 비어 있는지 확인합니다. -z
is는 [
명령 의 인수 일뿐 입니다. 변수 확장 [ -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
더 읽기 쉬울 수 있습니다.
=
하지 않고 가능한 경우 대신 표준 (POSIX) 연산자 를 사용해야합니다. ==
[
[[
set -o nounset
을 포함 합니다. #!/bin/bash
스크립트 맨 위에을 넣으면 실제로 bash의 향상된 기능을 사용하는 것이 가장 좋습니다.
이것이 위에서 요구 한 사용 사례 와 정확히 일치 하지는 않지만 기본 동작 을 사용 nounset
(또는 -u
) 하려는 경우 원하는 동작 인 설명 메시지와 함께 0이 아닌 상태를 종료하는 것입니다.
해결책으로 게시 할 가치가 있다고 생각한 것을 깨닫는 데 시간이 충분히 걸렸습니다.
종료 할 때 다른 것을 에코하거나 정리를 수행하는 것뿐이라면 트랩을 사용할 수 있습니다.
:-
연산자를 사용하면, 그렇지 않으면 원하는 아마.