programing

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

easyjava 2023. 4. 14. 22:16
반응형

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의 'Autoconf', 'Autoconf', 'Autoconf', 'Autoconf', 'Autoconf', 'Autoconf', 'Autoconf', 'Autoconf 'Autoconf'와하는 것은 권장하지 않습니다-a '는 간단한 를 따로 &&이치그것은, 과거에 존재하지 않았던 것은 아닙니다(그러나, 옛날에는 드물지 않았어도, 현재는 매우 드물 것입니다).

이들 및 기타 관련 셸 파라미터 확장, 또는 명령어 및 조건식에 대한 자세한 내용은 Bash 매뉴얼을 참조하십시오.


저는 최근 이 답변에 대해 다음과 같은 질문을 이메일로 받았습니다.

당신은 두 가지 테스트를 사용하고 있고, 저는 두 번째 테스트는 잘 이해하지만 첫 번째 테스트는 잘 이해하지 못합니다.더 정확히 말하면 변수 확장의 필요성을 이해하지 못합니다.

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 is not set"이라고 표시되지만, 내 테스트에서는 "VAR is not set"이라고 표시됩니다(아무것도 에코하지 않기 때문에 암시에 의해). "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은 전혀 설정되어 있지 않습니다.MP:1 VAR은 전혀 설정되어 있지 않다.MP:2 VAR은 전혀 설정되어 있지 않습니다.

두 번째 테스트 쌍에서는 변수가 설정되지만 빈 값으로 설정됩니다.이게 바로 그 차이점입니다.${VAR=value} ★★★★★★★★★★★★★★★★★」${VAR:=value}표기가 만들어지다.에 대해서도 마찬가지입니다.${VAR-value} ★★★★★★★★★★★★★★★★★」${VAR:-value} , , , , 입니다.${VAR+value} ★★★★★★★★★★★★★★★★★」${VAR:+value}기타 등등.


길리대답에서 지적했듯이, 만약 당신이 도망친다면bashset -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

물론 이러한 방법 중 하나를 사용하여 '기본값' 대신 원하는 값을 지정하고 필요에 따라 직접 확장을 사용합니다.

Advanced Bash 스크립트 가이드, 10.2.파라미터 대체:

  • ${var+blahblah: var가 정의되어 있으면 식 대신 'blahblah'가 사용되고, 그렇지 않으면 null이 대체됩니다.
  • ${var-blahblah: var가 정의되어 있으면 var 자체가 대체되고, 그렇지 않으면 'blahblah'가 대체됩니다.
  • ${var?blahblah: var가 정의되어 있으면 var가 대체되고, 그렇지 않으면 함수가 오류 메시지로 'blahblah'와 함께 존재합니다.

변수 $mystr이 정의되어 있는지 여부에 따라 프로그램 로직을 작성하려면 다음을 수행합니다.

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

이제 isdefined=0이면 변수가 정의되지 않았고, isdefined=1이면 변수가 정의되었습니다.

은 이전 , 되지 않은 변수 시 가 발생하도록 되어 있는 입니다.(set -u)스크립트가 조기에 종료됩니다.

기타 유용한 정보:

정의되지 않은 경우 기본값 7을 $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"

정의되는 변수를 확인하는 명확한 방법은 다음과 같습니다.

[ -v mystr ]

"set -o 명사 집합"을 사용할 때 변수가 bash로 설정되어 있는지 테스트하기 위해 더 나은 답이 포함되어 있는지 확인합니다(가독성이 뛰어나고 함께 작동합니다).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

다른 옵션: "list array indexs" 확장:

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

Bash 참조 매뉴얼은 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에서는 빠른 regex를 사용하여 이를 자동화할 수 있었습니다.

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

이는 관련 라인을 시각적으로 선택한 다음 다음을 입력하여 적용할 수 있습니다.:. 명령 모음에 미리 입력되어 있습니다.:'<,'>. 위의 명령어를 붙여넣고 를 누릅니다.


다음 버전의 Vim에서 테스트되었습니다.

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

Windows 유저는, 다른 행의 엔딩을 필요로 하는 경우가 있습니다.

자전거를 더 이상 떨어뜨리지 않으려고 하지만

shopt -s -o nounset

스크립트 상부에 추가할 수 있습니다.스크립트 내에 변수가 선언되어 있지 않으면 오류가 발생합니다.

표시되는 메시지는 바인딩되지 않은 변수이지만 다른 사용자가 언급했듯이 빈 문자열이나 null 값을 잡지 못합니다.

개별 값이 비어 있지 않은지 확인하기 위해 변수를 다음과 같이 확장할 때 테스트할 수 있습니다.${mystr:?}는 달러 기호 확장이라고도 하며 에러가 발생합니다.parameter null or not set.

변수가 정의되어 있는지 여부를 확인하는 훨씬 명확한 방법은 다음과 같습니다.

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

정의되지 않은 변수를 테스트하기 위한 짧은 버전은 다음과 같습니다.

test -z ${mystr} && echo "mystr is not defined"

인수 없는 호출 집합...정의된 모든 변수를 출력합니다.

목록의 마지막 항목은 스크립트에 정의된 항목입니다.

따라서 그 출력을 정의되어 있는 것과 정의되어 있지 않은 것을 파악할 수 있는 무언가에 연결할 수 있습니다.

언급URL : https://stackoverflow.com/questions/228544/how-to-tell-if-a-string-is-not-defined-in-a-bash-shell-script

반응형