스크립트에서 변수 할당에 "$ {a : -b}"사용


426

다른 사람들이 작성한 몇 가지 스크립트 (특히 Red Hat)를 살펴 봤으며 많은 변수가 다음 표기법을 사용하여 할당 VARIABLE1="${VARIABLE1:-some_val}" 되거나 다른 변수가 확장되었습니다. VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"

값을 직접 선언하는 대신이 표기법을 사용하는 요점은 무엇입니까 (예 :) VARIABLE1=some_val?

이 표기법 또는 가능한 오류로 인한 이점이 있습니까?

는 않습니다 :-이러한 맥락에서 특별한 의미를 가지고?


보세요 man bash; "매개 변수 확장"블록을 검색하십시오 (약 28 %). 이러한 할당은 예를 들어 기본 기능입니다. "아직 설정되지 않은 경우에만 기본값을 사용하십시오."
Hauke ​​Laging

답변:


695

이 기술을 사용하면 다른 변수가 비어 있거나 정의되지 않은 경우 변수에 값을 할당 할 수 있습니다. 참고 : 이 "다른 변수"는 동일하거나 다른 변수 일 수 있습니다.

발췌

${parameter:-word}
    If parameter is unset or null, the expansion of word is substituted. 
    Otherwise, the value of parameter is substituted.

참고 : 이 양식도 작동합니다 ${parameter-word}. Bash에서 사용할 수있는 모든 형식의 매개 변수 확장 목록을 보려면 Bash Hacker의 Wiki에서 " Parameter expansion " 이라는 제목의 주제를 살펴 보는 것이 좋습니다 .

변수가 존재하지 않습니다
$ echo "$VAR1"

$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
default value
변수가 존재
$ VAR1="has value"
$ echo "$VAR1"
has value

$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
has value

다른 변수를 평가하거나 표기법의 기본값 부분 내에서 명령을 실행하여 동일한 작업을 수행 할 수 있습니다.

$ VAR2="has another value"
$ echo "$VAR2"
has another value
$ echo "$VAR1"

$

$ VAR1="${VAR1:-$VAR2}"
$ echo "$VAR1"
has another value

더 많은 예

위치가 약간 다른 표기법을 사용할 수도 있습니다 VARX=${VARX-<def. value>}.

$ echo "${VAR1-0}"
has another value
$ echo "${VAR2-0}"
has another value
$ echo "${VAR3-0}"
0

위에서 $VAR1& $VAR2는 이미 "다른 값이 있습니다"라는 문자열 $VAR3로 정의 되었지만 정의되지 않았으므로 기본값이 대신 사용되었습니다 0.

또 다른 예

$ VARX="${VAR3-0}"
$ echo "$VARX"
0

:=표기법을 사용하여 확인 및 할당

마지막으로 편리한 연산자에 대해 언급하겠습니다 :=. 테스트중인 변수가 비어 있거나 정의되지 않은 경우 검사를 수행하고 값을 할당합니다.

공지 사항 $VAR1설정되었습니다. 운영자 :=는 단일 작업으로 테스트 및 할당을 수행했습니다.

$ unset VAR1
$ echo "$VAR1"

$ echo "${VAR1:=default}"
default
$ echo "$VAR1"
default

그러나 값이 미리 설정되어 있으면 그대로 유지됩니다.

$ VAR1="some value"
$ echo "${VAR1:=default}"
some value
$ echo "$VAR1"
some value

핸디 댄디 참조 표

    테이블의 ss

참고 문헌


8
이 모든 확장이에 설명되어 있지는 않습니다 bash. ${var:-word}질문의 하나이지만,하지 ${var-word}상술. POSIX 문서에는 멋진 테이블이 있지만이 답변에 복사 할 가치가 있습니다 -pubs.opengroup.org/onlinepubs/9699919799/utilities/…
Graeme

5
@Graeme, 그것은 문서화되어 있습니다, 당신 은 설정되지 않은 매개 변수에 대해서만 테스트에서 콜론 결과를 생략하는
Stéphane Chazelas

7
echo "${FOO:=default}"실제로 원하는 경우 사용하는 것이 좋습니다 echo. 그러나 그렇지 않으면 :내장 기능 을 사용해보십시오 ... : ${FOO:=default} 귀하의 위와 같이 $FOO설정되어 default있습니다 (즉, 아직 설정되지 않은 경우). 그러나 그 $FOO과정에서 메아리가 없습니다 .
fbicknel

2
Ok, 답변을 찾았습니다 : stackoverflow.com/q/24405606/1172302 . ${4:-$VAR}의지를 사용하면 효과 가 있습니다.
Nikos Alexandris

1
여기에 +1하여 500으로 데려갑니다. 축하합니다! :)
XtraSimplicity

17

@slm에는 이미 매우 유용한 POSIX 문서가 포함되어 있지만 실제로 이러한 매개 변수를 결합하여 서로 영향을 줄 수있는 방법에 대해서는 설명하지 않습니다. 이 양식에 대한 언급은 아직 없습니다.

${var?if unset parent shell dies and this message is output to stderr}

이것은 내 다른 답변 에서 발췌 한 것이며, 이것이 어떻게 작동하는지 잘 보여줍니다.

    sh <<-\CMD
    _input_fn() { set -- "$@" #redundant
            echo ${*?WHERES MY DATA?}
            #echo is not necessary though
            shift #sure hope we have more than $1 parameter
            : ${*?WHERES MY DATA?} #: do nothing, gracefully
    }
    _input_fn heres some stuff
    _input_fn one #here
    # shell dies - third try doesnt run
    _input_fn you there?
    # END
    CMD
heres some stuff
one
sh: line :5 *: WHERES MY DATA?

같은 다른 예 :

    sh <<-\CMD
    N= #N is NULL
    _test=$N #_test is also NULL and
    v="something you would rather do without"    
    ( #this subshell dies
        echo "v is ${v+set}: and its value is ${v:+not NULL}"
        echo "So this ${_test:-"\$_test:="} will equal ${_test:="$v"}"
        ${_test:+${N:?so you test for it with a little nesting}}
        echo "sure wish we could do some other things"
    )
    ( #this subshell does some other things 
        unset v #to ensure it is definitely unset
        echo "But here v is ${v-unset}: ${v:+you certainly wont see this}"
        echo "So this ${_test:-"\$_test:="} will equal NULL ${_test:="$v"}"
        ${_test:+${N:?is never substituted}}
        echo "so now we can do some other things" 
    )
    #and even though we set _test and unset v in the subshell
    echo "_test is still ${_test:-"NULL"} and ${v:+"v is still $v"}"
    # END
    CMD
v is set: and its value is not NULL
So this $_test:= will equal something you would rather do without
sh: line 7: N: so you test for it with a little nesting
But here v is unset:
So this $_test:= will equal NULL
so now we can do some other things
_test is still NULL and v is still something you would rather do without

위의 예는 POSIX 파라미터 치환 4 개 형태 활용 그들의 다양한 :colon null또는 not null시험. 위의 링크에 더 많은 정보가 있으며 여기에 다시 있습니다.

사람들이 종종 고려하지 않는 또 다른 사항은 ${parameter:+expansion}여기 문서에서 얼마나 유용한 지입니다. 다음은 다른 답변 에서 발췌 한 또 다른 내용입니다 .

상단

여기에 몇 가지 기본값을 설정하고 호출 될 때 인쇄 할 준비를합니다.

#!/bin/sh
    _top_of_script_pr() ( 
        IFS="$nl" ; set -f #only split at newlines and don't expand paths
        printf %s\\n ${strings}
    ) 3<<-TEMPLATES
        ${nl=
}
        ${PLACE:="your mother's house"}
        ${EVENT:="the unspeakable."}
        ${ACTION:="heroin"}
        ${RESULT:="succeed."}
        ${strings:="
            I went to ${PLACE} and saw ${EVENT}
            If you do ${ACTION} you will ${RESULT}
        "}
    #END
    TEMPLATES

가운데

여기에서 결과에 따라 인쇄 기능을 호출 할 다른 기능을 정의합니다.

    EVENT="Disney on Ice."
    _more_important_function() { #...some logic...
        [ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
            _top_of_script_pr
    }
    _less_important_function() { #...more logic...
        one=2
        : "${ACTION:="calligraphy"}"
        _top_of_script_pr
    }

바닥

이제 모든 설정이 완료되었으므로 여기에서 결과를 실행하고 가져올 수 있습니다.

    _less_important_function
    : "${PLACE:="the cemetery"}" 
    _more_important_function
    : "${RESULT:="regret it."}" 
    _less_important_function    

결과

잠시 이유를 살펴 보 겠지만 위의 내용을 실행하면 다음과 같은 결과가 나타납니다.

_less_important_function()'s 첫 실행 :

나는 당신의 어머니의 집에 가서 Disney on Ice를 보았습니다 .

당신이 경우에 서예를 당신은 성공합니다.

그때 _more_important_function():

나는 묘지에 가서 Disney on Ice를 보았습니다.

당신이 경우에 치료하는 수학을 당신은 성공합니다.

_less_important_function() 다시:

나는 묘지에 가서 Disney on Ice를 보았습니다.

교정 수학을하면 후회하게됩니다.

작동 방식 :

여기서 핵심 기능은 다음과 같은 개념입니다 conditional ${parameter} expansion.. 변수를 설정하지 않거나 null 형식으로 만 변수를 값으로 설정할 수 있습니다.

${var_name: =desired_value}

대신 설정되지 않은 변수 만 설정하려는 경우 :colon및 null 값은 그대로 유지됩니다.

범위 :

당신은 위의 예제에서 알 수 있습니다 $PLACE$RESULT를 통해 설정할 때 바뀌지 parameter expansion하더라도 _top_of_script_pr()그것을 실행할 때 아마도 그들을 설정, 이미 호출 된. 이 작품 이유는 즉 _top_of_script_pr()A는 ( subshelled )기능 - 나는 그것을 안에 parens댄 아니라 { curly braces }다른 사람을 위해 사용. 서브 쉘에서 호출되기 때문에 설정하는 모든 변수 locally scoped는 상위 쉘로 돌아가고 해당 값이 사라집니다.

그러나 _more_important_function()설정 하면 설정 $ACTIONglobally scoped다음을 통해서만 설정 되므로 _less_important_function()'s두 번째 평가에 영향을 미칩니다.$ACTION_less_important_function()$ACTION${parameter:=expansion}.


1
속기 기본값이 Bourne Shell
Sridhar Sarnobat

8

개인적인 경험.

예를 들어 다음과 같은 경우 값을 임시로 재정의하기 위해 스크립트에서이 형식을 사용하는 경우가 있습니다.

$ cat script.sh
SOMETHING="${SOMETHING:-something}"; echo "$SOMETHING"; 

나는 뛸 수있어:

$ env SOMETHING="something other than the default value" ./script.sh` 

원래 기본값 인을 변경할 필요가 없습니다 SOMETHING.

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