bash 변수가 비어 있는지 확인하는 방법은 무엇입니까?


답변:


1053

변수가 설정되지 않았거나 빈 문자열 ( "")로 설정되면 true를 반환합니다.

if [ -z "$VAR" ];

14
변수가 ""값으로 설정된 경우를 포함합니까?
Brent

11
"-z"는 길이가 0 인 문자열을 테스트합니다.
David Z

91
if [ ! -z "$VAR" ];
Aaron Copley

263
의 역은 -z이다-n if [ -n "$VAR" ];
펠리페 알바레즈

19
큰 따옴표는 변수가 분리되지 않도록합니다. $var명령 행 의 단순 은 공백으로 매개 변수 목록으로 분할되며 "$var"항상 하나의 매개 변수 만됩니다. 변수를 인용하는 것은 종종 좋은 습관이며 공백을 포함하는 파일 이름에서 다른 것들로 넘어 가지 않도록합니다. 예 : 수행 한 후 a="x --help", 시도 cat $a- 그것은 당신에게 도움말 페이지를 제공합니다 cat. 그런 다음 시도하십시오 cat "$a"-(보통) 말할 것 cat: x --help: No such file or directory입니다. 간단히 말해서, 빨리 인용하고 자주 인용하면 거의 후회하지 않을 것입니다.
Score_Under

247

Bash에서 쉘을 지원하지 않는 쉘로의 이식성에 관심이없는 경우 항상 이중 대괄호 구문을 사용해야합니다.

다음 중 하나 :

if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]

Bash에서 큰 대괄호를 사용하면 따옴표가 필요하지 않습니다. 당신은 변수에 대한 테스트를 단순화 할 수 있습니다 않는 값에 포함되어를 :

if [[ $variable ]]

이 구문은 ksh (적어도 ksh93 이상)와 호환됩니다. 순수 POSIX 또는 sh 또는 dash와 같은 이전 Bourne 쉘에서는 작동하지 않습니다.

보기 내 여기에 대답 하고 BashFAQ / 031 단일 및 이중 대괄호의 차이점에 대한 자세한 내용은.

변수가 구체적으로 설정되어 있지 않은지 테스트 할 수 있습니다 (빈 문자열과 구별됨).

if [[ -z ${variable+x} ]]

여기서 "x"는 임의입니다.

변수가 null이지만 설정되지 않은지 알고 싶은 경우 :

if [[ -z $variable && ${variable+x} ]]

1
그것은 if [[ $variable ]]나를 위해 잘 작동했으며 set -u다른 제안 된 솔루션 중 하나에 필요한 것을 필요로하지 않았습니다 .
Teemu Leisti

3
나는 이것이 받아 들인 대답보다 낫다고 생각합니다.
qed

2
이식 할 수없는 기능을 권장하는 이유는 무엇입니까?
Alastair 어바인

19
@AlastairIrvine : 내 대답의 첫 번째 문장에서 이식성을 언급했으며, 질문 제목과 본문에는 "Bash"라는 단어가 포함되어 있으며 질문에는 bash 태그가 지정 되어 있으며 이중 괄호 구조는 여러 가지면에서 분명한 이점 을 제공합니다 . 일관성과 유지 관리 성의 이유로 대괄호 스타일을 혼합하지 않는 것이 좋습니다. 최대, 최저 공통 분모 이식성이 필요한 경우 shBash 대신 사용하십시오 . 제공되는 향상된 기능이 필요한 경우 Bash를 사용하고 완전히 사용하십시오.
Dennis Williamson

2
@BrunoBronosky : 편집 내용을 되돌 렸습니다. ;마지막 에는 요구 사항이 없습니다 . 는 then전혀 세미콜론없이 다음 줄에있을 수 있습니다.
Dennis Williamson

230

bash (및 POSIX 호환 쉘)의 변수는 다음 세 가지 상태 중 하나 일 수 있습니다.

  • 설정 해제
  • 빈 문자열로 설정
  • 비어 있지 않은 문자열로 설정

대부분의 경우 변수가 비어 있지 않은 문자열로 설정되어 있는지 여부 만 알면되지만 설정되지 않은 문자열과 설정하지 않은 빈 문자열을 구분하는 것이 때때로 중요합니다.

다음은 다양한 가능성을 테스트하는 방법의 예이며 bash 또는 POSIX 호환 쉘에서 작동합니다.

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
    echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
    echo "VAR is either unset or set to a non-empty string"
fi

다음은 동일하지만 편리한 테이블 형식입니다.

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

${VAR+foo}경우 구조는 빈 문자열로 확장 VAR설정 해제하거나 foo경우에 VAR아무것도 설정 (빈 문자열 포함).

${VAR-foo}구조체는 다음의 값으로 확장 VAR세트 (빈 문자열로 설정 포함) 경우 foo해제합니다. 이는 사용자가 재정의 할 수있는 기본값을 제공하는 데 유용합니다 (예 : 변수 가 설정 되지 않은 경우 ${COLOR-red}사용하도록 지시).redCOLOR

[ x"${VAR}" = x ]변수가 설정되지 않았는지 또는 빈 문자열로 설정되어 있는지 테스트하는 데 종종 권장되는 이유 는 [명령 의 일부 구현 ( test버그 라고도 함 ) 때문입니다. 하면 VAR뭔가로 설정처럼 -n, 다음 몇 가지 구현이 주어 졌을 때 잘못된 일을 할 것이다 [ "${VAR}" = "" ]첫 번째 인수가 있기 때문에 [잘못 해석되어 -n운영자가 아닌 문자열입니다.


3
빈 문자열로 설정된 변수 테스트는을 사용하여 수행 할 수도 있습니다 [ -z "${VAR-set}" ].
nwellnhof

@nwellnhof : 감사합니다! 더 짧은 구문을 사용하도록 답변을 업데이트했습니다.
Richard Hansen

첫 번째와 마지막 구조의 차이점은 무엇입니까? 둘 다 "VAR이 설정되지 않았거나 비어 있지 않은 문자열로 설정되었습니다"에 해당합니다.
Faheem Mitha

1
@FaheemMitha : 그것은 당신의 잘못이 아닙니다. 제 대답은 읽기 어려웠습니다. 대답을 더 명확하게하기 위해 표를 추가했습니다.
Richard Hansen

2
설정되지 않은 검사는 신뢰할 수 없습니다. 사용자 가 bash set -u또는 set -o nounsetbash를 호출 한 경우 테스트에서 "bash : VAR : unbound variable"오류가 발생합니다. 보다 안정적인 설정 해제 확인 은 stackoverflow.com/a/13864829 를 참조 하십시오. 변수가 null인지 또는 설정되지 않은지 확인하십시오 [ -z "${VAR:-}" ]. 변수가 비어 있지 않은지 확인하는 것은 [ "${VAR:-}" ]입니다.
Kevin Jin

38

-z 가장 좋은 방법입니다.

내가 사용한 또 다른 옵션은 변수를 설정하는 것이지만 다른 변수로 재정의 할 수 있습니다.

export PORT=${MY_PORT:-5432}

경우 $MY_PORT변수가 비어, 다음 PORT, 그렇지 않으면 PORT가의 값으로 설정되어, 5432으로 설정됩니다 MY_PORT. 구문에는 콜론과 대시가 포함됩니다.


오늘 우연히 이것을 발견했으며, 내가 원하는 바로 그 것입니다. 감사! set -o nounset일부 스크립트에서는 용납해야합니다 .
opello

24

set-empty와 unset 상태의 경우를 구별하려면 bash의 -u 옵션을보십시오.

$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR

$ [ -z "$BAR" ] && echo true
true

8

내가 본 대안 [ -z "$foo" ]은 다음과 같지만 사람들이 왜이 방법을 사용하는지 잘 모르겠습니다.

[ "x${foo}" = "x" ]

어쨌든 설정되지 않은 변수 (by set -u또는 set -o nounset)를 허용하지 않으면 두 가지 방법 모두에서 문제가 발생할 수 있습니다 . 이것에 대한 간단한 수정이 있습니다.

[ -z "${foo:-}" ]

참고 : 이렇게하면 변수가 undef로 남습니다.


3
에 대한 대안에 대한 코멘트있다 -z에서 pubs.opengroup.org/onlinepubs/009695399/utilities/test.html은 . 기본적으로 이는의 대안이 아닙니다 -z. 오히려 $foo메타 문자로 시작 [하거나 test혼동 될 수 있는 것으로 확장 될 수있는 경우를 처리합니다 . 처음에 임의의 메타 데이터가 아닌 문자를 넣으면 그러한 가능성이 사라집니다.
James Sneeringer

6

질문은 요청 변수가 빈 문자열인지 확인하는 방법 과 최고의 답변이 이미 주어진다.
그러나 나는 PHP로 프로그래밍이 끝난 후 여기에 도착했으며 실제로 검색 한 것은 bash 쉘에서 작동하는 PHP빈 함수 와 같은 검사였습니다 .
답변을 읽은 후에 나는 bash에서 올바르게 생각하지 않는다는 것을 알았지 만, 그 순간 PHP에서 empty 와 같은 함수 는 내 bash 코드에서 너무 유용 할 것입니다.
나는 이것이 다른 사람들에게 일어날 수 있다고 생각하면서 bash에서 php empty 함수를 변환하기로 결정했다 .php 매뉴얼

에 따르면 :
변수가 존재하지 않거나 값이 다음 중 하나 인 경우 비어있는 것으로 간주됩니다.

  • ""(빈 문자열)
  • 0 (정수로 0)
  • 0.0 (플로트로 0)
  • "0"(문자열로 0)
  • 빈 배열
  • 선언되었지만 값이없는 변수

물론 nullfalse의 경우는 bash로 변환 할 수 없으므로 생략됩니다.

function empty
{
    local var="$1"

    # Return true if:
    # 1.    var is a null string ("" as empty string)
    # 2.    a non set variable is passed
    # 3.    a declared variable or array but without a value is passed
    # 4.    an empty array is passed
    if test -z "$var"
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is zero (0 as an integer or "0" as a string)
    elif [ "$var" == 0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is 0.0 (0 as a float)
    elif [ "$var" == 0.0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return
    fi

    [[ $( echo "" ) ]]
}



사용 예 :

if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



데모 :
다음 스 니펫 :

#!/bin/bash

vars=(
    ""
    0
    0.0
    "0"
    1
    "string"
    " "
)

for (( i=0; i<${#vars[@]}; i++ ))
do
    var="${vars[$i]}"

    if empty "${var}"
        then
            what="empty"
        else
            what="not empty"
    fi
    echo "VAR \"$var\" is $what"
done

exit

출력 :

VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty

bash 논리 에서이 기능에서 0을 확인하면 부수적 인 문제가 발생할 수 있다고 말했지만이 기능을 사용하는 사람은 누구나이 위험을 평가하고 첫 번째 검사 만 남기고 해당 검사를 중단하기로 결정할 수 있습니다.


함수 내부 empty-왜 [[ $( echo "1" ) ]] ; return간단하게 쓰지 않았 return 1습니까?
Dor

5

if-then 및 -z 전체가 필요하지 않습니다.

[ "$ foo"] && echo "foo가 비어 있지 않습니다"
[ "$ foo"] || echo "foo는 실제로 비어 있습니다"

3
foo에 공백 만 있으면 실패합니다
Brian

2
foo 가 옵션으로 해석되어 대시로 시작 하면 일부 쉘에서 실패 합니다. 예를 들어 solaris ksh , zshbash 에 문제가 없습니다. sh/ bin / test 가 실패합니다
ktf

4

$ FOO가 설정되어 있고 비어있는 경우에만 해당됩니다.

[ "${FOO+x}" = x ] && [ -z "$FOO" ]

4

개인적으로보다 명확한 확인 방법을 선호하십시오.

if [ "${VARIABLE}" == "" ]; then
  echo VARIABLE is empty
else
  echo VARIABLE is not empty
fi

1
일부 쉘은 이중 등호를 허용하지 않습니다.
Dennis Williamson

1
문제는 배쉬에 관한 것이었다. bash를 사용하고 있습니다. 나를 위해 잘 작동합니다. 정확히 무엇에 대해 말하고 있습니까?
Fedir RYKHTIK

2
Bash를 사용하는 경우 이중 대괄호를 사용해야합니다. 내 이전 의견은 귀하의 답변을 읽고 다른 쉘을 사용하는 사람들에게 간단한 사실 진술이었습니다.
Dennis Williamson

단일 대괄호이 경우 확인하고, 참조하시기 바랍니다 serverfault.com/questions/52034/...
루카 Borrione


4

내 5 센트 : 이보다 짧은 구문 if ...이 있습니다.

VALUE="${1?"Usage: $0 value"}"

인수가 제공된 경우이 행은 VALUE를 설정하고 오류 발생시 스크립트 행 번호 앞에 오류 메시지를 인쇄하고 스크립트 실행을 종료합니다.

abs-guide 에서 다른 예제를 찾을 수 있습니다 («Example 10-7»검색).


0

정확한 대답은 아니지만이 트릭에 부딪 쳤습니다. 찾고있는 문자열이 "명령"에서 온 경우 실제로 env에 명령을 저장할 수 있습니다. 변수를 입력하고 if 문마다 매번 실행하면 대괄호가 필요하지 않습니다!

예를 들어이 명령은 데비안에 있는지 확인합니다.

grep debian /proc/version

전체 예 :

IS_DEBIAN="grep -i debian /proc/version"

if $IS_DEBIAN; then
  echo 'yes debian'
else
  echo 'non debian'
fi

따라서 이것은 빈 문자열을 확인하는 간접 방법 (매번 실행)과 같습니다 (명령에서 오류 응답을 확인하지만 빈 문자열을 반환하는 경우도 있음).

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