programing

변수가 Bash에 설정되어 있는지 확인하는 방법

batch 2023. 4. 11. 21:49
반응형

변수가 Bash에 설정되어 있는지 확인하는 방법

변수가 Bash에 설정되어 있는지 어떻게 알 수 있습니까?

예를 들어, 사용자가 함수에 첫 번째 파라미터를 부여했는지 어떻게 확인할 수 있습니까?

function a {
    # if $1 is set ?
}

(통상)올바른 방법

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

서 ''는${var+x}파라미터 확장으로, 이 경우 아무것도 평가되지 않습니다.var이 , 「unset」이 「unset」로 됩니다.x렇지지그

따옴표 삽입

할 수 .${var+x}"${var+x}"따옴표가 것(따옴표가 없는 것따옴표는 따옴표로 됩니다).x따옴표가 없음) (따옴표가 필요 없음) 또는 (따옴표가 필요 없음)에 (가 필요 없음)[ -z ]도 '[ -z "" ]을 사용하다

그러나 인용문은 안전하게 생략할 수 있고 모두에게 즉시 명확하지는 않지만(이 인용문의 번째 저자인 주요 Bash 코더에게도 명확하지 않음), 때때로 다음과 같이 인용문을 사용하여 솔루션을 작성하는 것이 더 나을 수 있습니다.[ -z "${var+x}" ]가능한 한 적은 비용으로 O(1) 속도 패널티를 부과합니다.첫 번째 작성자는 또한 이 솔루션을 사용하는 코드 옆에 코멘트로 이 답변에 대한 URL을 추가했습니다.이것에 의해, 인용문을 생략할 수 있는 이유에 대한 설명도 기재되어 있습니다.

(흔히) 잘못된 방법

if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi

이는 설정되지 않은 변수와 빈 문자열로 설정된 변수를 구분하지 않기 때문에 종종 잘못된 것입니다. 「」의 는 「」입니다.var='''바르는 공백'

unset와 "set to empty string"의 구별은 사용자가 확장자 또는 추가 속성 목록을 지정해야 하는 상황에서 필수적이며, 이를 지정하지 않으면 기본값이 공백이 아닌 반면 빈 문자열을 지정하면 스크립트에서 빈 확장자 또는 추가 속성 목록을 사용해야 합니다.

그러나 모든 시나리오에서 구분이 필수적인 것은 아닐 수 있습니다. 경우 ★★★★[ -z "$var" ]괜찮을 거야

null/non-zero 문자열 변수를 확인하려면(설정된 경우)

if [ -n "$1" ]

는는 it it it it it it it it it it와는 -z★★★★★★★★★★★★★★★★★★★를 사용하고 있다.-n more보다 .-z.

다음과 같이 사용할 수 있습니다.

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi

매개 변수가 설정되지 않았는지, 비어 있는지("Null") 또는 값으로 설정되었는지 테스트하는 방법은 다음과 같습니다.

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |       parameter      |     parameter   |    parameter    |
|   in script:       |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word}  | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word     | assign word     |
| ${parameter=word}  | substitute parameter | substitute null | assign word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+word} | substitute word      | substitute null | substitute null |
| ${parameter+word}  | substitute word      | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+

출처: POSIX: 파라미터 확장:

"substitute"로 표시된 모든 경우 식은 표시된 값으로 대체됩니다."assign"과 함께 표시된 모든 경우 파라미터가 해당 값을 할당받습니다.이 값도 식을 대체합니다.

이를 실제로 표시하려면:

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |  When FOO="world"    |  When FOO=""    |    unset FOO    |
|   in script:       |  (Set and Not Null)  |  (Set But Null) |     (Unset)     |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello}      | world                | hello           | hello           |
| ${FOO-hello}       | world                | ""              | hello           |
| ${FOO:=hello}      | world                | FOO=hello       | FOO=hello       |
| ${FOO=hello}       | world                | ""              | FOO=hello       |
| ${FOO:?hello}      | world                | error, exit     | error, exit     |
| ${FOO?hello}       | world                | ""              | error, exit     |
| ${FOO:+hello}      | hello                | ""              | ""              |
| ${FOO+hello}       | hello                | hello           | ""              |
+--------------------+----------------------+-----------------+-----------------+

여기에 기재되어 있는 대부분의 기술은 올바르지만, Bash 4.2에서는 변수의 값을 테스트하는 것이 아니라 변수의 존재에 대한 실제 테스트(man bash)를 지원합니다.

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

이 하면, 「 」, 「 」, 「 」로 때, 는 발생하지 .set -uset -o nounset 예를 접근법과는 모드(모드)를 사용합니다.[ -z.

다음 방법 중 하나를 사용하여 이를 수행하는 방법은 여러 가지가 있습니다.

if [ -z "$1" ]

$1이 늘 또는 설정 해제된 경우 성공합니다.

다른 답변의 POSIX 테이블은 항상 느리므로, 이에 대한 제 의견은 다음과 같습니다.

파라미터 전개 VARIABLE VARIABLE 있다 VARIABLE
${VARIABLE-default} $VARIABLE "" "default"
${VARIABLE=default} $VARIABLE "" $(VARIABLE="default")
${VARIABLE?default} $VARIABLE "" exit 127
${VARIABLE+default} "default" "default" ""
${VARIABLE:-default} $VARIABLE "default" "default"
${VARIABLE:=default} $VARIABLE $(VARIABLE="default") $(VARIABLE="default")
${VARIABLE:?default} $VARIABLE exit 127 exit 127
${VARIABLE:+default} "default" "" ""

각 그룹(앞에 콜론이 있는 경우와 없는 경우)에는 동일한 설정설정되지 않은 경우가 있기 때문에 다른 것은 빈 케이스의 처리 방법뿐입니다.

앞의 콜론에서는 빈 케이스와 설정되지 않은 케이스가 동일하기 때문에 가능한 한 사용합니다(사용).:=만 아니라.=( ( ( ( ( ( ( ( ( ( ( 。

제목:

  • 수단을 정하다VARIABLE있지 않다(비어 있지 않다).VARIABLE="something")
  • 수단VARIABLEempty /empty (비어 있습니다)VARIABLE="")
  • 설정되지 않은 수단VARIABLE않는다unset VARIABLE)

값:

  • $VARIABLE이치노
  • "default"결과는 제공된 대체 문자열임을 의미합니다.
  • ""결과는 늘(빈 문자열)임을 나타냅니다.
  • exit 127스크립트 실행이 종료 코드 127로 정지됨을 의미합니다.
  • $(VARIABLE="default")는 「」을 의미합니다."default" 그리고 그것VARIABLE설정되지 않음)도 (비어 있다)와 같이 됩니다."default".

변수가 비어 있지 않은지 확인하려면

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

반대로 변수가 설정되지 않았거나 비어 있는지 테스트합니다.

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

변수가 설정되어 있는지(빈지 또는 비어 있지 않은지) 확인하려면

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

변수가 설정되지 않은 경우 반대쪽에서는 다음과 같이 테스트합니다.

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments

메모

는 Bash에 을 맞춘 Bash에 을 맞추고 .bash붙이다

단답

Bash에서 명명된 변수만 처리하는 경우 이 함수는 빈 배열이라도 변수가 설정되었는지 항상 알려줍니다.

variable-is-set() {
    declare -p "$1" &>/dev/null
}

기능하는 이유

Bash 3.0에서는 Bash('3.0')의 경우var 변수입니다. 설 / 정설,,,,, is 。declare -p var는 다음과 같이 합니다.declarevar값이 "Code"를 합니다.0만약var으로 "미신고" 입니다.declare -p var합니다.stderr 코드 「Code(상태 코드)」를 합니다.1.★★★★★★ 。&>/dev/null는, 정규의 양쪽 .stdout ★★★★★★★★★★★★★★★★★」stderr합니다./dev/null상태 코드를 변경하지 않고, 표시되지 않습니다.이치노

Bash에서 다른 메서드가 실패할 수 있는 이유

  • [ -n "$var" ]: 이것은 다음 조건만 체크합니다.${var[0]}비어있지 않습니다. (Bash에서는,$var is is is is is와 ${var[0]}
  • [ -n "${var+x}" ]: 이것은 다음 조건만 체크합니다.${var[0]}설정되었습니다.
  • [ "${#var[@]}" != 0 ]: 이 체크는 적어도1개의 인덱스가$var설정되었습니다.

Bash에서 이 메서드가 실패했을 때

은 이름 변수: 이름 있는 변수)에만됩니다.$_ 변수 「특정 변수」)가 $!,$@,$#,$$,$*,$?,$-,$0,$1,$2, ..., 그리고 잊어버렸을지도 모르는 것).어레이가 에, 스타일의 POSIX 는 입니다.[ -n "${var+x}" ]는 이러한 모든 특수 변수에 대해 작동합니다.그러나 함수가 호출될 때 많은 특수 변수가 값/존재를 변경하므로 함수로 묶는 것에 주의하십시오.

셸 호환성 노트

한 를 사용하는 것을 .typeset -pdeclare -pksh는 전자만 지원한다고 읽었지만 테스트 할 수 없었습니다.3.0.5 Bash 3.0+ Zsh 5.5.1을 있습니다.typeset -p ★★★★★★★★★★★★★★★★★」declare -p둘 중 하나가 다른 하나를 대체할 수 있는 것만 다릅니다. 저는 이 가지 껍데기도 .하다

POSIX sh 호환 스크립트가 필요한 경우 어레이를 사용할 수 없습니다.어레이가 경우, 레레 without without without[ -n "{$var+x}" ]

Bash의 다른 메서드 비교 코드

함수는 변수 를 실행합니다.var,eval는 패스된 코드를 하여 테스트를 하여 '실행', '실행', '실행'var에 의해 설정됩니다.evald 코드의 .

★★★★★★★★★★★★★★★★★★는 생략합니다test -v var,[ -v var ] , , , , 입니다.[[ -v var ]] POSIX와 를 얻을 수 입니다.[ -n "${var+x}" ]4.2 가 하지만, Bash 4.2+ 가 필요합니다.건너뛸게typeset -p입니다.declare -p(Bash 3.0 ~ 5.0 ( Zsh 5.5.1 ) 。

is-var-set-after() {
    # Set var by passed expression.
    unset var
    eval "$1"

    # Run the tests, in increasing order of accuracy.
    [ -n "$var" ] # (index 0 of) var is nonempty
    nonempty=$?
    [ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
    plus=$?
    [ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
    count=$?
    declare -p var &>/dev/null # var has been declared (any type)
    declared=$?

    # Show test results.
    printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}

테스트 케이스 코드

변수가 연관 배열로 선언되지 않은 경우 Bash가 숫자 이외의 배열 인덱스를 "0"으로 처리하므로 테스트 결과가 예상 밖일 수 있습니다.또한 연관 배열은 Bash 4.0+에서만 유효합니다.

# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo"                        #  0  0  0  0
is-var-set-after "var=(foo)"                      #  0  0  0  0
is-var-set-after "var=([0]=foo)"                  #  0  0  0  0
is-var-set-after "var=([x]=foo)"                  #  0  0  0  0
is-var-set-after "var=([y]=bar [x]=foo)"          #  0  0  0  0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''"                         #  1  0  0  0
is-var-set-after "var=([0]='')"                   #  1  0  0  0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')"                   #  1  1  0  0
is-var-set-after "var=([1]=foo)"                  #  1  1  0  0
is-var-set-after "declare -A var; var=([x]=foo)"  #  1  1  0  0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()"                         #  1  1  1  0
is-var-set-after "declare -a var"                 #  1  1  1  0
is-var-set-after "declare -A var"                 #  1  1  1  0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var"                      #  1  1  1  1

테스트 출력

은 에 하고 있습니다.[ -n "$var" ],[ -n "${var+x}" ],[ "${#var[@]}" != 0 ] , , , , 입니다.declare -p var각각 다음과 같다.

                         test: -n +x #@ -p
                      var=foo:  0  0  0  0
                    var=(foo):  0  0  0  0
                var=([0]=foo):  0  0  0  0
                var=([x]=foo):  0  0  0  0
        var=([y]=bar [x]=foo):  0  0  0  0
                       var='':  1  0  0  0
                 var=([0]=''):  1  0  0  0
                 var=([1]=''):  1  1  0  0
                var=([1]=foo):  1  1  0  0
declare -A var; var=([x]=foo):  1  1  0  0
                       var=():  1  1  1  0
               declare -a var:  1  1  1  0
               declare -A var:  1  1  1  0
                    unset var:  1  1  1  1

요약

  • declare -p var &>/dev/null (100%?)는 적어도 3.0 이후부터 Bash에서 명명된 변수를 테스트하는 데 신뢰성이 있습니다.
  • [ -n "${var+x}" ] 는 POSIX 준거 상황에서는 신뢰성이 높지만 어레이를 처리할 수 없습니다.
  • 변수가 비어 있지 않은지 여부를 확인하고 다른 셸에서 선언된 변수를 확인하기 위한 다른 검정이 있습니다.단, 이러한 테스트는 Bash 스크립트나 POSIX 스크립트에는 적합하지 않습니다.
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

인수의 경우 보통 인수 개수인 $#을 테스트하는 것이 가장 좋습니다.

if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

최신 버전의 Bash(4.2 이후, 확실히는 모르지만)에서는, 다음과 같이 시험합니다.

if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
    echo "Variable is unset"
elif [ -z "$SOMEVARIABLE" ]
then
    echo "Variable is set to an empty string"
else
    echo "Variable is set to some string"
fi

요약

  • test -n "${var-}"변수가 비어 있지 않은지 확인합니다(따라서 정의/설정도 필요합니다).

    if test -n "${var-}"; then
      echo "var is set to <$var>"
    else
      echo "var is not set or empty"
    fi
    
  • test -n "${var+x}"변수가 정의/설정되었는지 확인합니다(빈 변수인 경우에도).

    if test -n "${var+x}"; then
      echo "var is set to <$var>"
    else
      echo "var is not set"
    fi
    

첫 번째 사용 사례는 셸 스크립트에서 훨씬 더 일반적이며, 이는 일반적으로 사용하는 것입니다.

메모들

  • 이 솔루션은 모든 POSIX 쉘(sh, bash, zsh, ksh, 대시)에서 작동합니다.
  • 이 질문에 대한 다른 답변 중 일부는 맞지만 셸 스크립팅에 익숙하지 않은 사람들에게는 혼란스러울 수 있기 때문에 그러한 사람들에게는 가장 혼란스럽지 않은 TLDR 답변을 제공하고자 합니다.

설명.

이 솔루션의 구조를 이해하려면 POSIX 명령어와 POSIX 쉘 파라미터 확장(스펙)을 이해해야 합니다.따라서 답변을 이해하기 위해 필요한 절대적인 기본에 대해 설명하겠습니다.

진위를 검사하다 「」-n오퍼랜드가 비어 있지 않은 문자열인 경우 true를 반환합니다.를 들어, '예'라고 하면test -n "a"하고 true를 반환한다.test -n ""거짓으로 속이다비어 있지 해야 함)를하려면 , 「변수」를 할 수 있습니다test -n "$var"셸 옵션 세트( 「 」, 「 」)가 set -u되지 않은 가 에러일 var을 하겠습니다.$var에러가 발생합니다.이 문제를 올바르게 처리하려면 변수 확장을 사용해야 합니다.변수가 정의되지 않은 경우 변수를 대체 문자열로 대체하도록 셸에 지시하여 앞서 언급한 오류를 방지해야 합니다.

확장 " " "${var-} " "의 : "var정의되다' ('defined') 을 사용하다 ★★★★★★★★★★★★★★★★★.test -n "${var-}"만약 그렇다면 실현될 것이다.$var을 사용하다이것은 셸 스크립트에서 체크하는 거의 모든 것입니다. 체크의 )$var비어있지 는 "비어 있지 않습니다"가 됩니다.test -z "${var-}".

'가'가 있는지 확인합니다.var정의되어 있습니다.이는 일반적인 사용 사례는 아니지만 조금 더 복잡합니다. Lionels의 훌륭한 답변을 읽어보시면 더 잘 이해할 수 있습니다.

스크립트에서 설정되지 않았거나 비어 있지 않은지 확인하는 사용자:

if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi

의 「」[ -z "$var" ]var; unbound variableset -u[ -z "${var-}" ] 경우 빈 문자열로 확장됩니다.var을 사용하다

설정되지 않은 경우 종료합니다.

이건 나한테 효과가 있었어.파라미터가 설정되지 않은 경우 스크립트를 종료하고 오류 메시지를 표시하려고 했습니다.

#!/usr/bin/env bash

set -o errexit

# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"

실행 시 오류와 함께 반환됩니다.

peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument

확인만, 종료 없음 - 비어 있음 및 설정되지 않음은 유효하지 않음

값이 설정되어 있는지 확인하고 싶다면 이 옵션을 사용해 보세요=유효 또는 설정 해제/비어 있음=무효한.

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

또는 간단한 테스트도 가능합니다;-)

[ "${TSET:-}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"

선택만, 종료 없음 - 비어 있음만 유효하지 않습니다.

그리고 이것이 그 질문에 대한 대답입니다.값이 set/empty=인지 확인하고 싶은 경우 사용합니다.유효 또는 설정 해제=무효한.

주의: "..-1"의 "1"은 중요하지 않습니다. 어떤 것이든 상관없습니다(예: x).

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

간단한 테스트

[ "${TSET+1}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"

질문에 정확하게 답하도록 도전해 주신 @mklement0(댓글)에게 이 답변을 바칩니다.

참조: 2.6.2 파라미터 확장

확장의 .bash pageman 을 선택합니다.파라미터 확장은 설정되는 변수에 대한 일반적인 테스트를 제공하지 않지만 파라미터가 설정되지 않은 경우 파라미터에 대해 몇 가지 작업을 수행할 수 있습니다.

예를 들어 다음과 같습니다.

function a {
    first_arg=${1-foo}
    # rest of the function
}

first_arg에 equal $1푸우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우우. ifa는 해야 하며 않은 경우 할 수 있습니다.파라미터가 지정되어 있지 않은 경우 과 같이 됩니다.파라미터가 지정되어 있지 않은 경우, 에러 메세지로 종료할 수 있습니다.

function a {
    : ${1?a must take a single argument}
    # rest of the function
}

( 「 「 「 」 )의 사용에 해 주세요.: 명령어로,됩니다.는 아무것도 않아요.$1않은 합니다.)

이 아닌되어 있는지 하려면 , 「」를 합니다.[ -n "$x" ]★★★★★★★★★★★★★★★★★★★★★★★★★★★

대부분의 경우 값이 비어 있는 변수를 설정되지 않은 변수와 동일한 방식으로 처리하는 것이 좋습니다.이 을 구분할 수 .[ -n "${x+set}" ] )"${x+set}"setx 경우 빈 됩니다.x설정되지 않았습니다).

되었는지 여부를 하려면 테스트합니다.$#이 값은 함수(또는 함수가 아닌 경우 스크립트에 전달되는 파라미터의 수)입니다(Paul의 답변 참조).

변수가 설정되어 있는지 여부를 판단하는 방법에 대한 OP의 질문에 명확하게 답하기 위해 라이오넬의 답변은 다음과 같습니다.

if test "${name+x}"; then
    echo 'name is set'
else
    echo 'name is not set'
fi

이 질문에는 이미 많은 답변이 있지만 변수 값을 명확하게 구별하기 위해 진정한 부울식을 제공한 질문은 없습니다.

다음은 제가 해결한 몇 가지 명확한 표현입니다.

+-----------------------+-------------+---------+------------+
| Expression in script  | name='fish' | name='' | unset name |
+-----------------------+-------------+---------+------------+
| test "$name"          | TRUE        | f       | f          |
| test -n "$name"       | TRUE        | f       | f          |
| test ! -z "$name"     | TRUE        | f       | f          |
| test ! "${name-x}"    | f           | TRUE    | f          |
| test ! "${name+x}"    | f           | f       | TRUE       |
+-----------------------+-------------+---------+------------+

이 같다, 같다, 이런 표현들이에요.test <expression>> <=>[ <expression> ]

주의해서 사용해야 할 기타 애매한 표현:

+----------------------+-------------+---------+------------+
| Expression in script | name='fish' | name='' | unset name |
+----------------------+-------------+---------+------------+
| test "${name+x}"     | TRUE        | TRUE    | f          |
| test "${name-x}"     | TRUE        | f       | TRUE       |
| test -z "$name"      | f           | TRUE    | TRUE       |
| test ! "$name"       | f           | TRUE    | TRUE       |
| test ! -n "$name"    | f           | TRUE    | TRUE       |
| test "$name" = ''    | f           | TRUE    | TRUE       |
+----------------------+-------------+---------+------------+

는 아무도 불명예스러울 정도로 찾기 어려운 테이블을 프로그래밍 방식으로 생성하기 위해 셸 스크립트를 작성하려 하지 않았다는 것이 놀랍다.코딩 기술을 배우러 왔으니 답을 코드로 표현해보는 건 어떨까요?:) 제 의견은 다음과 같습니다(모든 POSIX 쉘에서 작동해야 합니다).

H="+-%s-+-%s----+-%s----+-%s--+\n"       # table divider printf format
R="| %-10s | %-10s | %-10s | %-10s |\n"  # table row printf format

S='V'     # S is a variable that is set-and-not-null
N=''      # N is a variable that is set-but-null (empty "")
unset U   # U is a variable that is unset

printf "$H" "----------" "-------" "-------" "---------";
printf "$R" "expression" "FOO='V'" "FOO='' " "unset FOO";
printf "$H" "----------" "-------" "-------" "---------";
printf "$R" "\${FOO:-x}" "${S:-x}" "${N:-x}" "${U:-x}  "; S='V';N='';unset U
printf "$R" "\${FOO-x} " "${S-x} " "${N-x} " "${U-x}   "; S='V';N='';unset U
printf "$R" "\${FOO:=x}" "${S:=x}" "${N:=x}" "${U:=x}  "; S='V';N='';unset U
printf "$R" "\${FOO=x} " "${S=x} " "${N=x} " "${U=x}   "; S='V';N='';unset U
#                                  "${N:?x}" "${U:?x}  "
printf "$R" "\${FOO:?x}" "${S:?x}" "<error>" "<error>  "; S='V';N='';unset U
#                                            "${U?x}   "
printf "$R" "\${FOO?x} " "${S?x} " "${N?x} " "<error>  "; S='V';N='';unset U
printf "$R" "\${FOO:+x}" "${S:+x}" "${N:+x}" "${U:+x}  "; S='V';N='';unset U
printf "$R" "\${FOO+x} " "${S+x} " "${N+x} " "${U+x}   "; S='V';N='';unset U
printf "$H" "----------" "-------" "-------" "---------";

스크립트 실행 결과:

+------------+------------+------------+------------+
| expression | FOO='V'    | FOO=''     | unset FOO  |
+------------+------------+------------+------------+
| ${FOO:-x}  | V          | x          | x          |
| ${FOO-x}   | V          |            | x          |
| ${FOO:=x}  | V          | x          | x          |
| ${FOO=x}   | V          |            | x          |
| ${FOO:?x}  | V          | <error>    | <error>    |
| ${FOO?x}   | V          |            | <error>    |
| ${FOO:+x}  | x          |            |            |
| ${FOO+x}   | x          | x          |            |
+------------+------------+------------+------------+

이 스크립트에는 부작용 할당이 이루어졌을 때(또는 이루어지지 않았을 때) 표시하는 등의 몇 가지 기능이 누락되어 있지만, 더 야심찬 사람이 이 시작점을 가지고 실행하기를 원할 수도 있습니다.

에서는 Bash를 사용할 수 .-v내 the의 [[ ]]★★★★

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR

「」를 사용합니다.[[ -z "$var" ]] 알 수 있는 이지만, 이 은 "예"로 "예"예외"입니다.-z는 설정되지 빈설정된

$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset" 
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset

env variable, parameter, regular variable 등 변수 유형에 따라 체크하는 것이 좋습니다.

env 변수의 경우:

[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"

를 들어 파라미터의 $5

[[ $# -ge 5 ]] && echo "Set" || echo "Unset"

정규 변수의 경우(보조 함수를 사용하여 우아하게 수행):

function declare_var {
   declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"

주의:

  • $#: 위치 파라미터의 수를 나타냅니다.
  • declare -p: 파라미터로 전달되는 변수의 정의를 제공합니다.존재하는 경우 0을 반환하고 없는 경우 1을 반환하고 오류 메시지를 출력합니다.
  • : 로부터의 출력을 억제합니다&> /dev/null.declare -p반환 코드에는 영향을 주지 않습니다.

" " " " " 가합니다.var is음 、 is is 、 is is 、 is is is is is is 。[ ${var+x} ].

이름으로 하려면:[ ${!name+x} ].

하려면:[ ${N+x} ]은은 은은 은은 은은 은은 은은은

이 답변은 라이오넬의 답변과 거의 유사하지만, 더 미니멀리즘적인 견해에 대해서는 생략합니다.-z.

명명된 변수가 설정되었는지 테스트하려면:

function is_set {
    local v=$1
    echo -n "${v}"
    if [ ${!v+x} ]; then
        echo " = '${!v}'"
    else
        echo " is unset"
    fi
}

위치 파라미터가 설정되어 있는지 테스트하려면:

function a {
    if [ ${1+x} ]; then
        local arg=$1
        echo "a '${arg}'"
    else
        echo "a: arg is unset"
    fi
}

테스트 결과 공백과 유효한 테스트 표현식에 대한 각별한 주의가 필요하지 않은 것으로 나타났습니다.

set -eu

V1=a
V2=
V4=-gt
V5="1 -gt 2"
V6="! -z 1"
V7='$(exit 1)'

is_set V1
is_set V2
is_set V3
is_set V4
is_set V5
is_set V6
is_set V7

a 1
a
a "1 -gt 2"
a 1 -gt 2
$ ./test.sh

V1 = 'a'
V2 = ''
V3 is unset
V4 = '-gt'
V5 = '1 -gt 2'
V6 = '! -z 1'
V7 = '$(exit 1)'
a '1'
a: arg is unset
a '1 -gt 2'
a '1'

「」에 해 주세요.set -eu변수 이름의 오타 등 일반적인 오류로부터 보호합니다.사용을 권장하지만 이는 설정되지 않은 변수와 빈 문자열로 설정된 변수 간의 차이가 올바르게 처리됨을 의미합니다.

다음 작업을 수행할 수 있습니다.

function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}

당신이 나와 같다면, 사실 당신이 찾고 있던 것은

"변수가 설정되어 있는 경우 명령어만 실행"

당신은 그것을 원라이너로 원하고 다음 행은 당신이 원하는 것입니다.

Bash 4.2 이후에서만 동작

설정된 경우에만 실행

if [[ -v mytest ]]; then echo "this runs only if variable is set"; fi

설정되지 않은 경우에만 실행

if [[ ! -v mytest2 ]]; then echo "this runs only if variable is not set"; fi

은 Bash 옵션인 Bash가 .set -u이네이블입니다.또한, 이들은 역동적이지 않다. 예를 들어, "dummy"라는 이름으로 가변성을 테스트하는 방법이 정의되어 있는가?이것을 시험해 보세요.

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}

관련:Bash에서 변수가 "-u" 모드로 정의되어 있는지 테스트하려면 어떻게 해야 합니까?

바람직한 방법은 다음과 같습니다.

$ var=10
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$ unset -v var
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set

기본적으로되면 '그 결과로 생기는 이false요?true= "구체적")

되지 않으면 '그로 생기는 ', '', '부정', '부정'true는)truefalse= "마음껏 먹어"

에서는, 「」를 할 수 .-z참. 참이다.

디폴트 설정을 MY_VAR설정되어 있지 않은 경우는, 필요에 따라서 다음의 메세지를 표시할 수 있습니다.

[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."

매일 사용하는 것은 다음과 같습니다.

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set() { [[ $(eval echo "\${${1}+x}") ]]; }

Linux 및 Solaris에서 Bash 3.0까지 정상적으로 동작합니다.

$ myvar="TEST"
$ is_set myvar ; echo $?
0

$ myvar=
$ is_set myvar ; echo $?
0

$ unset myvar
$ is_set myvar ; echo $?
1
[[ $foo ]]

또는

(( ${#foo} ))

또는

let ${#foo}

또는

declare -p foo

에서는 체크하고 좋은를 찾을 수 .$@.

[ $1 = " ]의 경우그리고나서에코 '$1이 공백'또 다른에코 '$1이 가득 찼습니다'fi

★★★★★★★★★★★★★의 모든 것$@이므로 Bash는 입니다.test -z ★★★★★★★★★★★★★★★★★」test -n도와줄 수 없었어요

업데이트: 파라미터의 문자수도 셀 수 있습니다.

[ ${#1} = 0 ]의 경우그리고나서에코 '$1이 공백'또 다른에코 '$1이 가득 찼습니다'fi
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi

모든 답을 대충 훑어본 후, 이것 또한 작동합니다.

if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"

SOME_VAR가 가지고 있는 $SOME_VAR으로 설정합니다. , 빈빈로설설 , 。$이 기능이 작동하기 위해 필요합니다.

언급URL : https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash

반응형