을 말하는 방법은 문자열인 경우에 정의되어 있지 않은 bash 쉘 스크립트를 사용해야 할까요?

StackOverflow https://stackoverflow.com/questions/228544

문제

하고 싶은 경우에 확인한 문자열이 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'그리고 서로 결합 된 별도의 간단한 테스트를 사용하는 것이 좋습니다. &&. 나는 문제가있는 시스템을 발견하지 못했습니다. 그렇다고해서 그들이 존재하지 않았다는 것을 의미하지는 않습니다 (그러나 먼 과거에는 드물지 않더라도 요즘 극히 드문 일 것입니다).

이들 및 기타 관련 세부 사항을 찾을 수 있습니다. 쉘 매개 변수 확장,, 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} 표기법이 만듭니다. ditto for ${VAR-value} 그리고 ${VAR:-value}, 그리고 ${VAR+value} 그리고 ${VAR:+value}, 등등.


처럼 길리 그의 지적 대답, 당신이 달리면 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는 정의되지 않은 변수에 대해서도 작동합니다. 정의되지 않은 것과 정의 된 것을 구별하려면 나열된 물건을 사용합니다. 여기 또는 명확한 설명으로 여기.

가장 깨끗한 방법은이 예에서와 같이 확장을 사용하는 것입니다. 모든 옵션을 얻으려면 매뉴얼의 매개 변수 확장 섹션을 확인하십시오.

대체 단어 :

~$ 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 정의,그 자체가 대체,다른 사람 'blahblah'는 대체
  • ${var?blahblah}:는 경우 var 정의 대체,다른 기능으로 존재'blahblah'로는 오류 메시지가 표시됩니다.


기반 프로그램 논리는지 여부에 변수$mystr 정의하거나,다음을 수행할 수 있습니다:

isdefined=0
${mystr+ export isdefined=1}

지금는 경우,정의되면=0 한 후에는 변수가 정의되지 않은 경우,정의되면=1 변수를 정의

이 방법을 확인하는 변수보다 더 위 응답이기 때문에 더 우아하고,읽을 수 있는,그리고 만약 당신의 bash 쉘하도록 구성되었에 오류가 사용하여 정의되지 않은 변수 (set -u), 스크립트가 종료 됩니다.


다른 유용한 물건:

하는 기본값은 7 할당$mystr 경우 그 정의되지 않은,그리고 그것을 떠나는 그대로 그렇지 않으면:

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

이 자전거를 더 이상 흘리지 말고 추가하고 싶었습니다.

shopt -s -o nounset

스크립트의 상단에 추가 할 수있는 것입니다. 변수가 아닌 경우 오류가 발생합니다. 선언 대본의 어느 곳에서나. 당신이 보는 메시지는입니다 unbound variable, 그러나 다른 사람들이 언급했듯이 빈 문자열이나 널 값을 잡을 수는 없습니다. 개별 값이 비어 있지 않도록하기 위해 변수가 확장되면서 변수를 테스트 할 수 있습니다. ${mystr:?}, 달러 기호 확장이라고도 알려져 있으며, 이는 오류가 발생합니다. parameter null or not set.

그만큼 강타 참조 매뉴얼 Bash에 대한 권위있는 정보 소스입니다.

다음은 변수를 테스트하여 존재하는지 확인하는 예입니다.

if [ -z "$PS1" ]; then
        echo This shell is not interactive
else
        echo This shell is interactive
fi

(에서 섹션 6.3.2.)

열린 후 공백이 있습니다 [ 그리고 전에 ] ~이다 선택 사항이 아닙니다.


VIM 사용자를위한 팁

다음과 같이 몇 가지 선언이있는 스크립트가있었습니다.

export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"

그러나 나는 그들이 기존 값을 연기하기를 원했습니다. 그래서 나는 그들에게 다음과 같이 보이도록 다시 작성합니다.

if [ -z "$VARIABLE_NAME" ]; then
        export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"
fi

나는 빠른 정규식을 사용하여 VIM에서 이것을 자동화 할 수있었습니다.

s/\vexport ([A-Z_]+)\=("[^"]+")\n/if [ -z "$\1" ]; then\r  export \1=\2\rfi\r/gc

관련 라인을 시각적으로 선택한 다음 타이핑하여 적용 할 수 있습니다. :. 명령 막대는 :'<,'>. 위 명령을 붙여 넣고 Enter를 누르십시오.


이 버전의 VIM에서 테스트 :

VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 22 2015 15:38:58)
Compiled by root@apple.com

Windows 사용자는 다른 라인 엔딩을 원할 수 있습니다.

다음은 변수가 정의되어 있는지 확인하는 훨씬 더 명확한 방법이라고 생각합니다.

var_defined() {
    local var_name=$1
    set | grep "^${var_name}=" 1>/dev/null
    return $?
}

다음과 같이 사용하십시오.

if var_defined foo; then
    echo "foo is defined"
else
    echo "foo is not defined"
fi

인수없이 호출 세트 .. 정의 된 모든 VAR을 출력합니다 ..
목록의 마지막 것은 스크립트에 정의 된 것입니다 ..
그래서 당신은 어떤 것들이 정의 된 것을 알아낼 수있는 것으로 출력을 파이프 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top