බෑෂ් විචල්‍යය හිස් දැයි තීරණය කරන්නේ කෙසේද?


787

බෑෂ් හි විචල්‍යයක් හිස් දැයි තීරණය කිරීමට හොඳම ක්‍රමය කුමක්ද ("")?

මා විසින් නිර්දේශ කරනු ලබන බව මා අසා ඇත if [ "x$variable" = "x" ]

එය නිවැරදි ක්‍රමයද? (වඩා සරල දෙයක් තිබිය යුතුය)


බලන්න: StackOverflow හි Bash හි ශුන්‍ය නොවන දිග නූල් සඳහා පරීක්ෂණය.
codeforester

බෑෂ් දී [[ -v VAR]]නම්, පරීක්ෂා කිරීමට VARඅර්ථ දක්වා ඇත, [[ -z $VAR ]]නම්, පරීක්ෂා කිරීමට ය "$VAR"ශූන්ය අනුලකුණු වැල (පුළුල් කර ඇති ""). මේ අනුව, ඔබට භාවිතා කළ හැකිය [[ -v VAR && -z $VAR ]]. වැඩි විස්තර මෙතැනින් කියවන්න (නිල යොමු සහිතව)
transang

Answers:


1083

විචල්‍යයක් සකසා නොමැති නම් හෝ හිස් නූලට ("") සකසා ඇත්නම් මෙය සත්‍ය වේ.

if [ -z "$VAR" ];

14
විචල්යයක් "" හි අගයකට සකසා ඇත්නම් එයට ඇතුළත් වේද?
බ්‍රෙන්ට්

11
ඔව් එය සිදු කරයි ... ශුන්‍ය දිග නූලක් සඳහා "-z" පරීක්ෂණ.
ඩේවිඩ් ඉසෙඩ්

95
if [ ! -z "$VAR" ];
ආරොන් කෝප්ලි

279
මෙහි ප්‍රතිලෝමය -zවන්නේ-n if [ -n "$VAR" ];
ෆෙලිපේ අල්වරෙස්

20
ද්විත්ව උපුටා දැක්වීම් මඟින් විචල්‍යය බෙදී නොයන බවට සහතික වේ. $varවිධාන රේඛාවක සරල එකක් එහි හිස් අවකාශය පරාමිති ලැයිස්තුවකට බෙදා ඇති අතර "$var"සෑම විටම එක් පරාමිතියක් පමණක් වනු ඇත. විචල්යයන් උපුටා දැක්වීම බොහෝ විට හොඳ පුරුද්දක් වන අතර සුදු අවකාශය අඩංගු ගොනු නාමයන් (වෙනත් දේ අතර) ඉහළට ඔසවා තැබීම වළක්වයි. උදාහරණය: කිරීමෙන් පසු a="x --help"උත්සාහ කරන්න cat $a- එය ඔබට උපකාරක පිටුව ලබා දෙනු catඇත. ඉන්පසු උත්සාහ කරන්න cat "$a"- එය (සාමාන්‍යයෙන්) කියනු cat: x --help: No such file or directoryඇත. කෙටියෙන් කිවහොත්, කලින් උපුටා දක්වන්න සහ බොහෝ විට උපුටා දක්වන්න, එවිට ඔබ කිසි විටෙකත් පසුතැවෙන්නේ නැත.
ලකුණු_අන්ඩර්

253

Bash හි, ඔබට සහාය නොදක්වන ෂෙල් වෙඩි සඳහා අතේ ගෙන යා හැකි බව ඔබ නොසලකන විට, ඔබ සැමවිටම ද්විත්ව වරහන සින්ටැක්ස් භාවිතා කළ යුතුය:

පහත සඳහන් ඕනෑම දෙයක්:

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

Bash හි, ද්විත්ව වර්ග වරහන් භාවිතා කරමින්, උපුටා දැක්වීම් අවශ්‍ය නොවේ. ඔබ විචල්යක් පරීක්ෂණය සරල හැකි කරන්නේ කිරීමට අගය අඩංගු:

if [[ $variable ]]

මෙම වාක්‍ය ඛණ්ඩය ksh සමඟ අනුකූල වේ (අවම වශයෙන් ksh93, කෙසේ වෙතත්). එය පිරිසිදු POSIX හෝ sh හෝ dash වැනි පැරණි බෝර්න් ෂෙල් වෙඩි වල ක්‍රියා නොකරයි.

ද්විත්ව සහ තනි වර්ග වරහන් අතර ඇති වෙනස්කම් පිළිබඳ වැඩි විස්තර සඳහා මගේ පිළිතුර මෙතැනින් සහ BashFAQ / 031 බලන්න .

විචල්‍යයක් නිශ්චිතවම සකසා නොමැතිදැයි බැලීමට ඔබට පරීක්ෂා කළ හැකිය (හිස් නූලකට වඩා වෙනස්ව):

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

එහිදී "x" අත්තනෝමතික වේ.

විචල්යයක් ශුන්ය නමුත් සැකසී නැතිදැයි ඔබට දැන ගැනීමට අවශ්ය නම්:

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

1
එය if [[ $variable ]]මට හොඳට වැඩ කළ set -uඅතර අනෙක් යෝජිත විසඳුම්වලින් එකක්වත් අවශ්‍ය නොවීය.
Teemu Leisti

3
පිළිගත් පිළිතුරට වඩා මෙය හොඳ යැයි මම සිතමි.
qed

2
අතේ ගෙන යා නොහැකි අංගයක් නිර්දේශ කිරීමෙන් එසේ කිරීමෙන් කිසිදු ප්‍රතිලාභයක් නොලැබෙන්නේ ඇයි?
ඇලෙස්ටෙයාර් ඉර්වින්

20
@AlastairIrvine: මම පහසුවෙන් එහාමෙහා ගෙන යාමේ මගේ පිළිතුර පළමු වාක්යය තුල, ප්රශ්නය මාතෘකාව සහ ශරීරය "බෑෂ් 'යන වචනය අඩංගු ප්රශ්නය ඈඳා වේ සඳහන් bash , සහ ද්විත්ව වරහන ව්යුහය ලබා පැහැදිලි වාසි බොහෝ ක්රම. අනුකූලතාව සහ නඩත්තු කිරීමේ හේතුන් මත වරහන් මෝස්තර මිශ්‍ර කිරීම මම නිර්දේශ නොකරමි. ඔබට උපරිම, අඩුම පොදු හරය අතේ ගෙන යා හැකි නම්, shBash වෙනුවට භාවිතා කරන්න. එය සපයන වැඩි හැකියාවන් ඔබට අවශ්‍ය නම්, Bash භාවිතා කර එය සම්පූර්ණයෙන්ම භාවිතා කරන්න.
වැඩිදුර දැනුම් දෙන තුරු විරාමය.

2
R බ un නෝ බ්‍රොනොස්කි: මම සංස්කරණය ආපසු හැරෙව්වා. ;අවසානයේ අවශ්‍යතාවයක් නොමැත . මෙම thenසියලු දී, semicolon තොරව ඉදිරි මාර්ගයේ විය හැක.
වැඩිදුර දැනුම් දෙන තුරු විරාමය.

239

බෑෂ් වල විචල්‍යයක් (සහ ඕනෑම 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}ඉදිකිරීමක් හිස් string පුළුල් නම් VARශූන්යය හෝ වේ fooනම්, VAR(හිස් string ඇතුළුව) කිසිවක් කිරීමට පියවර ගෙන තිබේ.

මෙම ${VAR-foo}ඉදිකිරීමක් වටිනාකම පුළුල් VAR(හිස් string කිරීමට මාලාවක් ඇතුළුව) කට්ටලයක් නම් fooශූන්යය නම්. පරිශීලක අභිබවා යා හැකි පෙරනිමි ලබා දීම සඳහා මෙය ප්‍රයෝජනවත් වේ (උදා: විචල්‍යය යම් දෙයකට සකසා නොමැති නම් ${COLOR-red}භාවිතා කිරීමට පවසයි ).redCOLOR

[ x"${VAR}" = x ]විචල්‍යයක් සැකසී තිබේද නැතිනම් හිස් නූලට සකසා තිබේද යන්න පරීක්ෂා කිරීම සඳහා බොහෝ විට නිර්දේශ කිරීමට හේතුව වන්නේ [විධානයෙහි සමහර ක්‍රියාත්මක testකිරීම් දෝෂ සහිත වීමයි. VARවැනි දෙයකට සකසා ඇත්නම් -n, සමහර ක්‍රියාවට නැංවීමේදී වැරදි දේ කරනු ඇත, [ "${VAR}" = "" ]මන්ද පළමු තර්කය [වැරදියට අර්ථකථනය කරන්නේ -nක්‍රියාකරු ලෙස මිස නූලක් ලෙස නොවේ.


3
හිස් නූලට විචල්ය කට්ටලයක් පරීක්ෂා කිරීම ද භාවිතා කළ හැකිය [ -z "${VAR-set}" ].
nwellnhof

wnwellnhof: ස්තූතියි! බ්‍රීෆර් සින්ටැක්ස් භාවිතා කිරීම සඳහා මම මගේ පිළිතුර යාවත්කාලීන කළෙමි.
රිචඩ් හැන්සන්

පළමු හා අවසාන ඉදිකිරීම් අතර වෙනස කුමක්ද? ඔවුන් දෙදෙනාම "VAR සකසා නැත හෝ හිස් නොවන නූලකට සකසා ඇත".
ෆහීම් මිත

1
A ෆහීම්මිතා: එය ඔබේ වරදක් නොවේ - මගේ පිළිතුර කියවීමට අපහසු විය. පිළිතුර වඩාත් පැහැදිලි කිරීමට මම මේසයක් එක් කළෙමි.
රිචඩ් හැන්සන්

2
සැකසූ චෙක්පත් විශ්වාසදායක නොවේ. පරිශීලකයා ඇමතුමක් set -uහෝ set -o nounsetබැෂ් එකක් නම්, පරීක්ෂණය මඟින් "bash: VAR: unbound variable" දෝෂය ඇතිවේ. බලන්න stackoverflow.com/a/13864829 වඩා විශ්වාසදායක ශූන්යය පරීක්ෂාකිරීම සඳහා. විචල්යයක් ශූන්‍යද, නැතිනම්ද යන්න පරීක්ෂා කර බැලීමට මගේ සංචාරය [ -z "${VAR:-}" ]. විචල්යයක් හිස් නොවේ දැයි මගේ චෙක්පත [ "${VAR:-}" ].
කෙවින් ජින්

39

-z හොඳම ක්‍රමයයි.

මා භාවිතා කළ තවත් විකල්පයක් වන්නේ විචල්‍යයක් සැකසීමයි, නමුත් එය වෙනත් විචල්‍යයක් මගින් අභිබවා යා හැක

export PORT=${MY_PORT:-5432}

නම් $MY_PORTවිචල්ය හිස්, පසුව PORTමාලාවක්, 5432 කිරීමට ලැබෙන වෙනත් ආකාරයකින් වරාය වටිනාකම කිරීමට සමූහයක් වේ MY_PORT. සින්ටැක්ස් වලට කොලන් සහ ඩෑෂ් ඇතුළත් බව සලකන්න.


1
අද අහම්බෙන් මෙය හමු වූ අතර එය මට අවශ්‍ය දේම විය. ස්තූතියි! set -o nounsetසමහර පිටපත් වල මට ඉවසිය යුතුයි .
ඔපෙලෝ

24

සැකසූ හිස් හා සැකසූ තත්වයන් වෙන්කර හඳුනා ගැනීමට ඔබ කැමති නම්, 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" ]

කෙසේ වෙතත්, ඔබ විසින් සැකසූ විචල්‍යයන් අනුමත නොකරන්නේ නම් (එක්කෝ set -uහෝ set -o nounset), එවිට ඔබ එම ක්‍රම දෙකම සමඟ කරදරයට පත්වේ. මේ සඳහා සරල විසඳුමක් තිබේ:

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

සටහන: මෙය ඔබගේ විචල්යය අවලංගු කරයි.


3
Pubs.opengroup.org/onlinepubs/009695399/utilities/test.html-z හි ඇති විකල්පය ගැන අදහස් දැක්වීමක් තිබේ . මූලික වශයෙන්, එය විකල්පයක් ලෙස අදහස් නොකෙරේ -z. ඒ වෙනුවට, එය අවස්ථා හසුරුවන $fooබව metacharacter පටන් දෙයක් පුළුල් විය හැකි [හෝ testව්යාකූල කරනු ඇත. ආරම්භයේ දී අත්තනෝමතික නොවන මෙටාචැක්ටරයක් ​​තැබීමෙන් එම හැකියාව ඉවත් වේ.
ජේම්ස් ස්නරිංගර්

6

මෙම ප්රශ්නය අසයි විචල්ය හිස් අගයක් වේ නම්, පරීක්ෂා කරන ආකාරය හා ඒ සඳහා ඇති හොඳම පිළිතුරු දැනටමත් ලබා දී ඇත.
නමුත් මම මෙහි පැමිණියේ ගොඩබෑමේ කාල පරිච්ඡේදයක් පසු php වලින් වන අතර ඇත්ත වශයෙන්ම මා සොයමින් සිටියේ php හි හිස් ශ්‍රිතය වැනි කඩඉමක් ලෙසය.
පිළිතුරු කියවීමෙන් පසුව මට වැටහුණා මම නිසි ලෙස සිතන්නේ නැති බව, නමුත් කෙසේ හෝ ඒ මොහොතේ දී php හි හිස් වැනි ශ්‍රිතයක් මගේ බාෂ් කේතයේ ඉතා පහසු වනු ඇත.
මෙය අනෙක් අයට සිදුවිය හැකි යැයි මා සිතන පරිදි, php හිස් ශ්‍රිතය bash ලෙස පරිවර්තනය කිරීමට මම තීරණය කළෙමි

. Php අත්පොතට අනුව :
විචල්‍යයක් නොපවතින නම් හෝ එහි අගය පහත සඳහන් එකක් නම් හිස් ලෙස සලකනු ලැබේ:

  • "" (හිස් නූලක්)
  • 0 (පූර්ණ සංඛ්‍යාවක් ලෙස 0)
  • 0.0 (0 පාවෙන ලෙස)
  • "0" (0 නූලක් ලෙස)
  • හිස් පෙළක්
  • විචල්‍යයක් ප්‍රකාශ කළ නමුත් අගයක් නොමැතිව

ඇත්ත වශයෙන්ම ශුන්‍ය හා අසත්‍ය සිද්ධීන් කඩිනමින් පරිවර්තනය කළ නොහැකි බැවින් ඒවා මඟ හැරී ඇත.

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



Demo:
පහත සඳහන් ඇබිත්ත:

#!/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

බාෂ් තර්කනයක දී මෙම ශ්‍රිතයේ ශුන්‍යය පිළිබඳ චෙක්පත් මගින් අතුරු ආබාධ ඇතිවිය හැකි බව පවසා ඇති අතර, මෙම ශ්‍රිතය භාවිතා කරන ඕනෑම අයෙකු මෙම අවදානම තක්සේරු කළ යුතු අතර සමහර විට එම චෙක්පත් පළමු එකෙන් ඉවත් කිරීමට තීරණය කළ හැකිය.


ශ්‍රිතය ඇතුළත empty- ඔබ [[ $( echo "1" ) ]] ; returnසරලව වෙනුවට ලිව්වේ ඇයි return 1?
ඩෝර්

5

if-then සහ -z සියල්ලම අනවශ්‍යය.

["$ foo"] && echo "foo හිස් නොවේ"
["$ foo"] || echo "foo ඇත්ත වශයෙන්ම හිස්"

4
Foo හි ඇත්තේ අවකාශයන් පමණක් නම් එය අසාර්ථක වනු ඇත
බ්‍රයන්

2
විකල්පයක් ලෙස අර්ථකථනය කර ඇති බැවින් foo ඉරකින් ආරම්භ වුවහොත් සමහර කවච වලද එය අසාර්ථක වනු ඇත . උදා: සූර්ය කෝෂ මත ksh , zsh සහ bash කිසිදු ගැටළුවක් නොවේ, sh සහ / bin / test අසමත් වනු ඇත
ktf

5

මගේ ශත 5: මෙයට වඩා කෙටි වාක්‍ය ඛණ්ඩයක් ද ඇත if ...:

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

මෙම රේඛාව තර්කයක් සපයා ඇත්නම් VALUE සකසනු ඇති අතර දෝෂයක් ඇති වුවහොත් ස්ක්‍රිප්ට් රේඛා අංකය සමඟ පෙර සැකසූ දෝෂ පණිවිඩයක් මුද්‍රණය කරනු ඇත (සහ ස්ක්‍රිප්ට් ක්‍රියාත්මක කිරීම අවසන් කරනු ඇත).

තවත් උදාහරණයක් අබ්ස්-මාර්ගෝපදේශයෙහි සොයාගත හැකිය («උදාහරණ 10-7 for සඳහා සොයන්න).


4

O FOO සකසා හිස් වූ විට මෙය හරියටම සත්‍ය වේ:

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

4

පරීක්ෂා කිරීමට වඩාත් පැහැදිලි ක්‍රමයක් පුද්ගලිකව කැමති:

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

1
සමහර කවච ද්විත්ව සමාන ලකුණ පිළිගන්නේ නැත.
වැඩිදුර දැනුම් දෙන තුරු විරාමය.

1
ප්රශ්නය වූයේ බාෂ් ගැන ය. මම පාවිච්චි කරනවා. මට හොඳින් වැඩ කරයි. ඔබ හරියටම කතා කරන්නේ කුමක් ගැනද?
Fedir RYKHTIK

2
ඔබ Bash භාවිතා කරන්නේ නම්, ඔබ ද්විත්ව වර්ග වරහන් භාවිතා කළ යුතුය. මගේ පෙර අදහස් දැක්වීම ඔබේ පිළිතුර කියවා වෙනත් කවචයක් භාවිතා කරන අයට සරල සත්‍ය ප්‍රකාශයකි.
වැඩිදුර දැනුම් දෙන තුරු විරාමය.

මෙම අවස්ථාවේදී තනි වර්ග වරහන් හරි, කරුණාකර serverfault.com/questions/52034/…
ලූකා බෝරියන්

4

දීර්ඝ oneliner duffbeer703 විසඳුම:

#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter

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

එබැවින් මෙය හිස් නූලක් පරික්ෂා කිරීම සඳහා වක්‍ර ක්‍රමයක් (සෑම අවස්ථාවකදීම එය නැවත ක්‍රියාත්මක කිරීම) වැනි ය (එය විධානයෙන් දෝෂ ප්‍රතිචාරයක් පරික්ෂා කිරීම සිදු වේ, නමුත් එය හිස් නූලක් ආපසු යැවීම ද සිදු වේ).

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.