ස්ක්‍රිප්ට් වල විචල්‍ය පැවරුම් සඳහා “$ {a: -b}” භාවිතා කිරීම


509

මම පිටපත් කිහිපයක් අනිත් අය ලියූ (විශේෂයෙන් Red Hat), සහ පහත සඳහන් අංකනය භාවිතයෙන් ඔවුන්ගේ විචල්ය ගොඩක් පවරා බලා තිබේ VARIABLE1="${VARIABLE1:-some_val}" හෝ වෙනත් පුළුල් විචල්යයන් VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"

අගයන් කෙලින්ම ප්‍රකාශ කිරීම වෙනුවට මෙම අංකනය භාවිතා කිරීමේ තේරුම කුමක්ද (උදා:) VARIABLE1=some_val?

මෙම අංකනයෙන් ප්‍රයෝජන හෝ වළක්වා ගත හැකි දෝෂ තිබේද?

මෙම වන්නේ :-මෙම සන්දර්භය තුළ නියමිත අර්ථයක් තිබේද?


බලන්න man bash; "පරාමිති පුළුල් කිරීම" වාරණය සොයන්න (28% ක් පමණ). මෙම පැවරුම් උදා: පෙරනිමි ශ්‍රිත: "පෙරනිමි අගය භාවිතා කරන්න කිසිවක් තවම සකසා නොමැති නම් පමණි."
Hauke ​​Laging

Answers:


820

මෙම තාක්‍ෂණය මඟින් වෙනත් විචල්‍යයක් හිස් හෝ නිර්වචනය කර නොමැති නම් විචල්‍යයකට අගයක් පැවරීමට ඉඩ ලබා දේ. සටහන: මෙම "වෙනත් විචල්‍යය" සමාන හෝ වෙනත් විචල්‍යයක් විය හැකිය.

උපුටා ගැනීම

${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 හි විකියෙහි මෙම මාතෘකාව දෙස බලන්නැයි මම තරයේ යෝජනා කරමි .

උදාහරණ

විචල්‍යය නොපවතී
$ 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/…
ග්‍රේම්

5
Ra ග්‍රේම්, එය ලේඛනගත කර ඇත, ඔබ මහා බඩවැලේ ප්‍රති results ල විමෝචනය කිරීම කෙරෙහි අවධානය යොමු කළ යුතුය .
ස්ටෙෆාන් චසෙලාස්

8
echo "${FOO:=default}"ඔබට සැබවින්ම අවශ්‍ය නම් භාවිතා කිරීම විශිෂ්ටයි echo. නමුත් ඔබ එසේ නොකළේ නම්, :ගොඩනංවා ගැනීමට උත්සාහ කරන්න ... : ${FOO:=default} ඔබේ ඉහත පරිදි $FOOසකසා defaultඇත (එනම්, දැනටමත් සකසා නොමැති නම්). නමුත් $FOOක්‍රියාවලිය තුළ දෝංකාරයක් නොමැත .
fbicknel

2
හරි, පිළිතුරක් හමු විය: stackoverflow.com/q/24405606/1172302 . ${4:-$VAR}කැමැත්ත භාවිතා කිරීම වැඩ කරයි.
නිකොස් ඇලෙක්සැන්ඩ්‍රිස්

1
+1 සවිස්තරාත්මක පිළිතුර සඳහා පමණි. නමුත් ඔබ විශිෂ්ට බාෂ් විකිය ගැන සඳහන් කරයි. තවද ඔබ උදාහරණ සහ වගුවක් ලබා දීම සඳහා. නිරය, +1s පහළට බැස ඇත :) මට නම් මට වාක්‍ය ඛණ්ඩය හරියටම තිබුනද එය එතරම් ප්‍රමාණවත් නොවීය - මෑන් පිටුව සෙවීමට තරම් මම නොසිතුවෙමි (අමාරු නැත, නමුත් එහි මාතෘකාව කුමක්දැයි මට මතක නැත මම අද උදේ 4 සිට අවදි වී සිටිමි :() ..
ප්‍රිෆ්ටන්

17

lslm දැනටමත් 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

මැද

ප්‍රති results ල මත පදනම්ව ඔබේ මුද්‍රණ ශ්‍රිතය ඇමතීමට වෙනත් කාර්යයන් ඔබ අර්ථ දක්වන්නේ මෙහිදීය ...

    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    

ප්රතිපල

මම මොහොතකට යන්නට යන්නෙමි, නමුත් ඉහත ධාවනය කිරීමෙන් පහත ප්‍රති results ල ලැබේ:

_less_important_function()'s පළමු ධාවනය:

මම ඔබේ මවගේ නිවසට ගොස් ඩිස්නි අයිස් මත දුටුවෙමි .

ඔබ අක්ෂර වින්‍යාසය කළහොත් ඔබ සාර්ථක වනු ඇත.

එවිට _more_important_function():

මම සුසාන භූමියට ගොස් ඩිස්නි අයිස් මත දුටුවෙමි.

ඔබ ප්‍රතිකර්ම ගණිතය කළහොත් ඔබ සාර්ථක වනු ඇත.

_less_important_function() යළි:

මම සුසාන භූමියට ගොස් ඩිස්නි අයිස් මත දුටුවෙමි.

ඔබ ප්‍රතිකර්ම ගණිතය කළහොත් ඔබ කනගාටු වනු ඇත .

එය කරන්නේ කෙසේද:

මෙහි ඇති ප්‍රධාන ලක්ෂණය නම් conditional ${parameter} expansion.ඔබට විචල්‍යයක් අගයකට සැකසිය හැක්කේ එය ආකෘති පත්රය භාවිතයෙන් සකසා නොමැති නම් පමණි.

${var_name: =desired_value}

ඒ වෙනුවට ඔබ සැකසූ විචල්‍යයක් පමණක් සැකසීමට අදහස් කරන්නේ නම්, ඔබ අතහැර දමනු ඇති :colonඅතර ශුන්‍ය අගයන් එලෙසම පවතිනු ඇත.

විෂය පථය මත:

ඔබ ඉහත සඳහන් උදාහරණය තුළ බව දක්නට විය $PLACEසහ $RESULTහරහා විට කට්ටලයක් වෙනස් වෙනවා parameter expansionවුවත් _top_of_script_pr()එය ගේ ලකුණු අනුමාන කිරීම ගැන, දැනටමත් කැඳවා තිබේ. මෙය ක්‍රියාත්මක වීමට හේතුව _top_of_script_pr()එය ( subshelled )ශ්‍රිතයකි - අනෙක් ඒවා සඳහා භාවිතා parensකරනවාට වඩා මම එය කොටු කර ගතිමි { curly braces }. එය උප කුලකයකින් හැඳින්වෙන නිසා, එය සකසන සෑම විචල්‍යයක්ම වන අතර එය locally scopedමව් කවචයට ආපසු යන විට එම අගයන් අතුරුදහන් වේ.

එහෙත් _more_important_function()කට්ටල $ACTIONඑය globally scopedඑය බලපාන නිසා _less_important_function()'sදෙවන ඇගයීම $ACTIONනිසා _less_important_function()කට්ටල $ACTIONඔස්සේ පමණක්${parameter:=expansion}.



10

පුද්ගලික අත්දැකීම.

සාරධර්ම ඉක්මවා යාම සඳහා මම සමහර විට මගේ ස්ක්‍රිප්ට් වල මෙම ආකෘතිය භාවිතා කරමි, උදා: මට තිබේ නම්:

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

මට දුවන්න පුළුවන්:

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

හි මුල් පෙරනිමි අගය වෙනස් නොකර SOMETHING.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.