Bash හි විචල්යයක් සකසා ඇත්දැයි පරීක්ෂා කරන්නේ කෙසේද?


1598

Bash හි විචල්යයක් සකසා ඇත්දැයි මා දැන ගන්නේ කෙසේද?

උදාහරණයක් ලෙස, පරිශීලකයා ශ්‍රිතයකට පළමු පරාමිතිය ලබා දුන්නේ දැයි පරීක්ෂා කරන්නේ කෙසේද?

function a {
    # if $1 is set ?
}

12
if test $# -gt 0; then printf 'arg <%s>\n' "$@"; fi.
ජෙන්ස්

218
විසඳුම් සොයන්නන්ට සටහන: "විචල්‍ය නොවන හිස්" යන ප්‍රශ්නයට පිළිතුරු සපයන මෙම ප්‍රශ්නයට ඉහළ ඇගයීමක් ඇති පිළිතුරු බොහොමයක් ඇත. වඩාත් නිවැරදි කිරීමේ විසඳුම් ("විචල්ය කට්ටලය") පහත ජෙන්ස් සහ ලයනල්ගේ පිළිතුරු වල සඳහන් වේ.
නේතන් කිඩ්

8
රසල් හර්මන් සහ සීමස් ඔවුන්ගේ -vපරීක්ෂණයෙන් නිවැරදි ය , මෙය නව සංස්කරණවල පමණක් ඇති බව පෙනෙන්නට තිබුණත් bashෂෙල් වෙඩි හරහා අතේ ගෙන යා නොහැකි ය.
ග්‍රේම්

5
Athan නාතන්කිඩ් පෙන්වා දුන් පරිදි, නිවැරදි විසඳුම් ලබා දෙන්නේ ලයනල් සහ ජෙන්ස් විසිනි. prosseek, ඔබ පිළිගත් පිළිතුර මෙයින් එකක් වෙත මාරු කළ යුතුය .
ගැරට්

3
... හෝ වැරදි පිළිතුරක් @prosseek මෙම ගැටලුව ආමන්ත්රණය කර නැත සිට, අප අතර සිටින වැඩි බුද්ධිමත් විසින් downvoted ගත හැක.
dan3

Answers:


2341

(සාමාන්යයෙන්) නිවැරදි මාර්ගය

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

එහිදී ${var+x}යනු පරාමිතිය පුළුල් නම් කිසිවක් ඇගයීමට ලක් කරන varශූන්යය වන අතර, වැල ආෙද්ශ ෙකෙර් xවෙනස් දෙයකි.

උපුටා ගැනීම උපුටා ගැනීම

මිල ගණන් මඟ හැරිය හැක (එබැවින් අපට පැවසිය හැකිය ${var+x}"${var+x}"උපුටා දැක්වීම් මඟ ඒ වෙනුවට ) මන්ද මෙම වාක්‍ය ඛණ්ඩය සහ භාවිතය සහතික කරන්නේ මෙය උපුටා දැක්වීම් අවශ්‍ය නොවන දෙයකට පමණක් ව්‍යාප්ත වන හෙයිනි (එය පුළුල් වන හෙයින් x(එහි වචන බිඳීමක් නොමැති බැවින් එය උපුටා දැක්වීම් අවශ්‍ය නොවේ), හෝ කිසිවක් නැත (එහි ප්‍රති results [ -z ]ලය වන්නේ එකම අගයට (සත්‍ය) පහසුවෙන්ම ඇගයීමට ලක් කිරීමයි [ -z "" ])).

කෙසේ වෙතත්, උපුටා දැක්වීම් ආරක්ෂිතව මඟ හැරිය හැකි අතර, එය වහාම සැමට පැහැදිලිව පෙනෙන්නට නොතිබුණි ( මෙම උපුටා දැක්වීම්වල පළමු කතුවරයාට ප්‍රධාන බාෂ් කෝඩරයක් වන පැහැදිලි කිරීමක් පවා පෙනෙන්නට නොතිබුණි ), සමහර විට විසඳුම ලිවීම වඩා හොඳ වනු ඇත ලෙස මිල කැඳවීම් සමග [ -z "${var+x}" ]ක සාමාන්ය (1) වේගය දණ්ඩනය ඉතා කුඩා විය හැකි වියදමින්. පළමු කතුවරයා මෙය කේතයට යාබදව විවරණයක් ලෙස මෙම විසඳුම භාවිතා කරමින් මෙම පිළිතුරට URL ලබා දී ඇති අතර, දැන් උපුටා දැක්වීම් ආරක්ෂිතව මඟ හැරිය හැක්කේ මන්ද යන්න පිළිබඳ පැහැදිලි කිරීමක් ද මෙහි ඇතුළත් ය.

(බොහෝ විට) වැරදි මාර්ගය

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

මෙය බොහෝ විට වැරදියි, මන්ද එය සකසා නැති විචල්‍යයක් සහ හිස් නූලට සකසා ඇති විචල්‍යයක් අතර වෙනස හඳුනා නොගන්නා බැවිනි. එනම්, එසේ නම්var='' , ඉහත විසඳුම මඟින් "var හිස්" ප්‍රතිදානය කරනු ඇත.

පරිශීලකයාට දිගුවක් හෝ අමතර දේපල ලැයිස්තුවක් නියම කළ යුතු අවස්ථාවන්හිදී, සැකසූ සහ “හිස් නූලට සකසා ඇති” අතර වෙනස අත්‍යවශ්‍ය වන අතර ඒවා පෙරනිමි හිස් නොවන අගයකට නියම නොකෙරේ. ස්ක්‍රිප්ටය හිස් දිගුවක් හෝ අතිරේක ගුණාංග ලැයිස්තුවක් භාවිතා කරන්න.

සෑම අවස්ථාවකම වෙනස අත්‍යවශ්‍ය නොවනු ඇත. එවැනි අවස්ථාවන්හිදී [ -z "$var" ]පමණක් හොඳ වනු ඇත.


29
Ar ගැරට්, ඔබේ සංස්කරණය මෙම පිළිතුර වැරදියි, ${var+x}භාවිතා කිරීමට නිවැරදි ආදේශනය වේ. භාවිතා කිරීමෙන් [ -z ${var:+x} ]වඩා වෙනස් ප්‍රති result ලයක් නොලැබේ [ -z "$var" ].
ග්‍රේම්

11
මෙය ක්‍රියාත්මක නොවේ. Var අගය අගයකට සකසා තිබේද නැද්ද යන්න නොසලකා මම "සකසා නැත" ("setet var" සමඟ නිෂ්කාශනය කර ඇත, "echo $ var" කිසිදු ප්‍රතිදානයක් නිපදවන්නේ නැත).
බ්‍රෙන්ට් 212

10
විසඳුමේ වාක්‍ය ඛණ්ඩය සඳහා {{පරාමිති + වචනය}, නිල අත්පොත කොටස gnu.org/software/bash/manual/… ; කෙසේ වෙතත්, එහි ඇති දෝෂයක්, එය මෙම වාක්‍ය ඛණ්ඩය ඉතා පැහැදිලිව සඳහන් නොකරන නමුත් උපුටා දැක්වීමක් පමණක් පවසයි (මහා බඩවැලෙන් ඉවත්වීම [":"] පරීක්ෂණයක ප්‍රති results ලය වන්නේ සැකසූ පරාමිතියක් සඳහා පමණි. $ {පරාමිතිය: + වචනය} [අර්ථය] පරාමිතිය ශුන්‍ය හෝ සැකසූ නම් කිසිවක් ආදේශ නොකෙරේ, එසේ නොමැතිනම් වචනයේ ප්‍රසාරණය ආදේශ වේ.); උපුටා ගත් ref pubs.opengroup.org/onlinepubs/9699919799/utilities/… (දැන ගැනීමට හොඳ) මෙහි වඩා පැහැදිලි ලියකියවිලි ඇත.
ගමනාන්ත ගෘහ නිර්මාණ ශිල්පියා

8
එය උදා, ඔබ සතුව ප්රකාශන භාවිතා කරන විට මිල කැඳවීම් අවශ්ය වගේ [ -z "" -a -z ${var+x} ]ලැබෙන bash: [: argument expectedbash 4.3-උබුන්ටු (නමුත් උදා zsh) හි. සමහර අවස්ථාවල වැඩ කිරීමට සිදු වන සින්ටැක්ස් භාවිතයෙන් මම පිළිතුරට අකමැතියි.
FauxFaux

42
සරල භාවිතා කිරීම [ -z $var ]උපුටා දැක්වීම් මඟ හැරීමට වඩා "වැරදි" නොවේ. කෙසේ හෝ ඔබ ඔබේ ආදානය ගැන උපකල්පන සිදු කරයි. ඔබ හිස් නූලක් සැකසූ ලෙස සලකන්නේ නම්, [ -z $var ]ඔබට අවශ්‍ය වන්නේ එයයි.
nshew

923

ශුන්‍ය නොවන / ශුන්‍ය නොවන නූල් විචල්‍යය පරීක්ෂා කිරීම සඳහා, එනම් සකසා ඇත්නම් භාවිතා කරන්න

if [ -n "$1" ]

එය ප්‍රතිවිරුද්ධ දෙයකි -z. මම -nවඩා භාවිතා කරන බව මට පෙනේ -z.

ඔබ එය භාවිතා කරන්නේ:

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

87
මම සාමාන්යයෙන් කැමති [[ ]]පුරා [ ]ලෙස, [[ ]]වඩාත් powerfull වන අතර සමහර අවස්ථාවල දී අඩු ප්රශ්න හේතු (බලන්න මේ ප්රශ්නය ඒ දෙක අතර ඇති වෙනස පැහැදිලි කිරීමක් සඳහා). ප්රශ්නය විශේෂයෙන් කඩිනම් විසඳුමක් ඉල්ලා සිටින අතර කිසිදු අතේ ගෙන යා හැකි අවශ්යතා සඳහන් නොකරයි.
ගලා යන්න

19
ප්‍රශ්නය වන්නේ විචල්‍යයක් සකසා ඇත්දැයි යමෙකුට පෙනෙන්නේ කෙසේද යන්නයි . විචල්ය බව එවිට ඔබට උපකල්පනය කළ නොහැකි කට්ටලයක්.
HelloGoodbye

7
මම එකඟයි, []විශේෂයෙන් ෂෙල් (බාෂ් නොවන) ස්ක්‍රිප්ට් සඳහා වඩා හොඳින් ක්‍රියා කරයි.
හෙන්ජි


63
-nඑය පෙරනිමි පරීක්ෂණය බව සලකන්න , එබැවින් වඩාත් සරලව [ "$1" ]හෝ [[ $1 ]]වැඩ කරන්න. [[ ]] උපුටා දැක්වීම සමඟ අනවශ්‍ය බව සලකන්න .
tne

491

පරාමිතියක් සකසා නොමැතිද , නැතිනම් හිස්ද ("ශූන්‍ය") හෝ අගයකින් සකසා තිබේද යන්න පරීක්ෂා කරන්නේ කෙසේද යන්න මෙන්න :

+--------------------+----------------------+-----------------+-----------------+
|   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 |
+--------------------+----------------------+-----------------+-----------------+

මූලාශ්‍රය: පොසික්ස්: පරාමිති පුළුල් කිරීම :

"ආදේශක" සමඟ පෙන්වා ඇති සෑම අවස්ථාවකම, ප්‍රකාශනය පෙන්වා ඇති අගය සමඟ ප්‍රතිස්ථාපනය වේ. "පැවරුම" සමඟ පෙන්වා ඇති සෑම අවස්ථාවකම පරාමිතිය එම අගය පවරනු ලබන අතර එය ප්‍රකාශනය ප්‍රතිස්ථාපනය කරයි.

මෙය ක්‍රියාවෙන් පෙන්වීමට:

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |  FOO="world"         |     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           | ""              |
+--------------------+----------------------+-----------------+-----------------+

5
El හෙලෝ ගුඩ්බි ඔව් එය ක්‍රියාත්මක වේ: set foo; echo ${1:-set but null or unset}දෝංකාරය "foo"; set --; echo ${1:-set but null or unset}echoes set but null ...
Jens

4
El හෙලෝ ගුඩ්බයි ස්ථානීය පරාමිතීන් සමඟ සැකසිය හැකිය, අහ් , set:-)
ජෙන්ස්

98
මෙම පිළිතුර ඉතා ව්‍යාකූල ය. මෙම වගුව භාවිතා කරන්නේ කෙසේද යන්න පිළිබඳ ප්‍රායෝගික උදාහරණ තිබේද?
බෙන් ඩේවිස්

12
En බෙන්ඩාවිස් POSIX ප්‍රමිතියට සබැඳියෙන් විස්තර කර ඇති අතර, එමඟින් වගුව ගෙන ඇති පරිච්ඡේදය සඳහන් කරයි. මා ලියන ඕනෑම ස්ක්‍රිප්ට් එකක පාහේ භාවිතා කරන එක් ඉදිකිරීමක් : ${FOOBAR:=/etc/foobar.conf}නම් විචල්‍යයක් සඳහා පෙරනිමි අගයක් සැකසීම හෝ ශුන්‍ය නම් එය සැකසීමයි.
ජෙන්ස්

1
parameterඕනෑම විචල්‍ය නාමයකි. wordයනු ඔබ භාවිතා කරන වගුවේ ඇති වාක්‍ය ඛණ්ඩය සහ විචල්‍යය $parameterසකසා තිබේද , සකසා ඇති නමුත් ශුන්‍යද, නැතහොත් සැකසූද යන්න මත පදනම්ව ආදේශ කිරීම සඳහා වන නූලකි. දේවල් වඩාත් සංකීර්ණ කිරීමට නොව, wordවිචල්‍යයන් ද ඇතුළත් කළ හැකිය! අක්ෂරයකින් වෙන් කරන ලද විකල්ප ආග්ස් පසු කිරීම සඳහා මෙය ඉතා ප්‍රයෝජනවත් වේ. උදාහරණයක් ලෙස: ${parameter:+,${parameter}}කොමාව ,$parameterසකසා ඇති නමුත් ශුන්‍ය නොවන්නේ නම් එය වෙන් කරනු ලැබේ. මෙම අවස්ථාවේ දී, wordයනු,${parameter}
ට්‍රිනිට්‍රොන්එක්ස්

269

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

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

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

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

භාවිතා කිරීම වැනි වෙනත් බොහෝ ප්‍රවේශයන් මෙන් නොව, set -u/ set -o nounsetප්‍රකාරයේදී සැකසූ විචල්‍යයක් / මාදිලියේ පරික්ෂා කිරීමේදී මෙම ප්‍රවේශය දෝෂයක් ඇති නොකරනු ඇත [ -z.


9
4.1.2 හි, විචල්‍යය සකසා තිබේද යන්න නොසලකා, [[ -v aaa ]]; echo $?==>-bash: conditional binary operator expected -bash: syntax error near 'aaa'
ඩෑන්

33
'ටෙස්ට්' බිල්ඩින් සඳහා '-v' තර්කය බාෂ් 4.2 හි එකතු කරන ලදි.
Ti Strga

19
-v තර්කය -u shell විකල්පයට (නාමපදය) අනුපූරකයක් ලෙස එකතු කරන ලදි. 'නාමපදය' සක්‍රිය කිරීමෙන් (set -u), කවචය දෝෂයක් ගෙන එය අන්තර්ක්‍රියාකාරී නොවේ නම් අවසන් වේ. ස්ථානීය පරාමිතීන් පරීක්ෂා කිරීම සඳහා $ # හොඳයි. කෙසේ වෙතත්, නම් කරන ලද විචල්‍යයන්ට ඒවා සැකසූ ඒවා ලෙස හඳුනා ගැනීම සඳහා ක්ලෝබර් කිරීම හැර වෙනත් ක්‍රමයක් අවශ්‍ය විය. බොහෝ අය කලින් අනුවාදයට අනුකූල වීමට බැඳී සිටින නිසා මෙම අංගය මෙතරම් ප්‍රමාද වී තිබීම අවාසනාවකි, එම අවස්ථාවේදී ඔවුන්ට එය භාවිතා කළ නොහැක. අනෙක් විකල්පය නම් ඉහත පෙන්වා ඇති පරිදි එය වටා ගමන් කිරීම සඳහා උපක්‍රම හෝ 'හක්ස්' භාවිතා කිරීමයි, නමුත් එය වඩාත්ම අනවශ්‍යය.
osirisgothra

2
ප්‍රකාශිත නමුත් සැකසූ විචල්‍යයන් සඳහා මෙය ක්‍රියා නොකරන බව සලකන්න. උදාdeclare -a foo
miken32

19
පිළිගත් / වැඩිම ඡන්දය දුන් පිළිතුරෙන් පසුව මම දිගටම කියවන්නේ මේ නිසා ය.
ජෝ

176

පහත සඳහන් ඒවායින් එකක් වීමත් සමඟ මෙය කිරීමට බොහෝ ක්‍රම තිබේ:

if [ -z "$1" ]

$ 1 ශුන්‍ය හෝ සැකසූ නම් මෙය සාර්ථක වේ


47
සැකසූ පරාමිතියක් සහ ශුන්‍ය අගයක් සහිත පරාමිතියක් අතර වෙනසක් ඇත.
චෙප්නර්

22
මට අවශ්‍ය වන්නේ ව්‍යාකූල වීමට සහ ප්‍රශ්නය මතු කරන දෙයට ප්‍රතිවිරුද්ධ පිළිතුර මෙයයි. ප්රශ්න අසන්නේ විචල්ය IS සකසා ඇත්ද, විචල්යය සකසා නොමැති නම් නොවේ.
ෆිලුමිනාටි

47
[[ ]]අතේ ගෙන යා හැකි අන්තරායක් මිස අන් කිසිවක් නොවේ. if [ -n "$1" ]මෙහි භාවිතා කළ යුතුය.
ජෙන්ස්

73
මෙම පිළිතුර වැරදිය. ප්‍රශ්නය අසන්නේ විචල්‍යයක් සකසා තිබේද යන්න මිස එය හිස් නොවන අගයකට සකසා තිබේද යන්න පැවසීමට ක්‍රමයක් මගිනි. ලබා foo=""දී $fooඇත, වටිනාකමක් ඇත, නමුත් -zඑය හිස් බව වාර්තා කරයි. හා -z $fooතිබේ නම්, ඔබ පුපුරවා ඇත set -o nounset.
කීත් තොම්සන්

4
එය "විචල්යය සකසා ඇත" යන්නෙහි අර්ථ දැක්වීම මත රඳා පවතී. විචල්‍යය ශුන්‍ය නොවන නූලකට සකසා ඇත්දැයි පරීක්ෂා කිරීමට ඔබට අවශ්‍ය නම් , mbranning පිළිතුර නිවැරදි ය. නමුත් විචල්‍යය ප්‍රකාශ කර ඇති නමුත් ආරම්භ කර නොමැතිදැයි පරීක්ෂා කිරීමට ඔබට අවශ්‍ය නම් (එනම් foo=), රසල්ගේ පිළිතුර නිවැරදි ය.
ගලා යන්න

81

මම සෑම විටම අනෙක් පිළිතුරෙහි POSIX වගුව සෙමෙන් සෙමෙන් සෙමෙන් සොයා ගතිමි, එබැවින් මෙන්න මම එය භාර ගනිමි:

   +----------------------+------------+-----------------------+-----------------------+
   |   if VARIABLE is:    |    set     |         empty         |        unset          |
   +----------------------+------------+-----------------------+-----------------------+
 - |  ${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"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

එක් එක් කණ්ඩායමක (සමග සහ මහ බඩවැලේ පෙර තොරව) එම ඇති බව සටහන කට්ටලයක් හා ශූන්යය නඩු නිසා මෙයින් වෙනස් වූ ආකාරය බව එකම දේ හිස් නඩු සිදු කරනු ලැබේ.

පූර්ව මහා බඩවැල සමඟ, හිස් හා සැකසූ නඩු එක සමාන වේ, එබැවින් මම හැකි සෑම විටම භාවිතා කරමි (එනම් හිස් නඩුව නොගැලපෙන නිසා :=පමණක් භාවිතා කරන්න =).

ශීර්ෂයන්:

  • set means VARIABLEයනු හිස් නොවන ( VARIABLE="something")
  • හිස් මාධ්‍යයන් VARIABLEහිස් / ශූන්‍ය ( VARIABLE="")
  • සැකසූ මාධ්‍යයන් VARIABLEනොපවතී ( unset VARIABLE)

වටිනාකම්:

  • $VARIABLE එහි ප්‍රති result ලය වන්නේ විචල්‍යයේ මුල් අගයයි.
  • "default" එහි ප්‍රති result ලය වූයේ ප්‍රතිස්ථාපන නූල ලබා දීමයි.
  • "" එහි ප්‍රති result ලය ශුන්‍යයි (හිස් නූලක්).
  • exit 127 පිටපත 127 පිටවීමේ කේතය සමඟ ක්‍රියාත්මක වීම නවත්වයි.
  • $(VARIABLE="default")ප්රතිඵලය විචල්ය මුල් අගය අදහස් වන්නේ හා සපයා ඇති වෙනුවට string අනාගත භාවිතය සඳහා විචල්ය අනුයුක්ත කර ඇත.

1
ඔබ නියම කර ඇත්තේ සත්‍ය කේතීකරණ දෝෂ (විචල්‍යයන් සමඟ වැඩ කිරීමේදී අනවශ්‍ය උදාසීනතාවයේ අවස්ථා) ය. විස්තරය අර්ථ නිරූපණය කිරීමේදී ඩොලරයේ වෙනසක් සිදු වන තවත් අවස්ථා කිහිපයක් නිවැරදි කිරීමට මම සංස්කරණයක් කළෙමි. BTW, සියලුම ෂෙල් විචල්යයන් (අරා හැර) නූල් විචල්යයන් වේ; ඒවා සංඛ්‍යාවක් ලෙස අර්ථ දැක්විය හැකි නූලක් අඩංගු වීම සිදුවිය හැකිය. නූල් ගැන කතා කිරීම පණිවිඩය මීදුමෙන් පමනි. උපුටා දැක්වීම්වලට නූල් සමග කිසිදු සම්බන්ධයක් නැත, ඒවා පැන යාමට විකල්පයක් පමණි. VARIABLE=""ලෙස ලිවිය හැකිය VARIABLE=. තවමත්, කලින් කියවා ඇති දේ වඩාත් කියවිය හැකිය.
පලෙක්

වගුවට ස්තූතියි එය ඉතා ප්‍රයෝජනවත් වේ, කෙසේ වෙතත් මම උත්සාහ කරන්නේ සැකසූ හෝ හිස් නම් ස්ක්‍රිප්ට් පිටවීමටයි. නමුත් මට ලැබෙන පිටවීමේ කේතය 1 නොව 127 වේ.
ගගනගාමී

64

විචල්‍යයක් නිරුපද්‍රිතව තිබේදැයි බැලීමට, මම භාවිතා කරමි

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

මමත් කාලයක් තිස්සේ මෙය භාවිතා කර ඇත්තෙමි. අඩු ආකාරයකින්:[ $isMac ] && param="--enable-shared"

H භස්කර් මම හිතන්නේ එයට හේතුව මෙම පිළිතුර දැනටමත් අත්‍යවශ්‍යයෙන්ම එකම පිළිතුර ( iff සකසා ${variable+x}ගැනීමට භාවිතා කරන්න ) වසර භාගයකට පමණ පෙර ලබා දී ඇති බැවිනි. එය නිවැරදි වන්නේ ඇයිද යන්න පැහැදිලි කිරීමට තවත් බොහෝ විස්තර ඇත. x$variable
මාර්ක් හැෆර්කැම්ප්

35

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

5
[ -v "$VARNAME" ]එය වැරදි නොවන බව සලකන්න , නමුත් වෙනත් පරීක්ෂණයක් සිදු කරයි. සිතමු VARNAME=foo; fooසකසා ඇති විචල්‍යයක් තිබේදැයි පරීක්ෂා කරයි.
චෙප්නර්


එකක් ලැබුනේ නම් [: -v: unexpected operator, bashඒ වෙනුවට භාවිතා කිරීම සහතික කළ යුතුය sh.
කොප්පෝර්

25
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

තර්ක සඳහා සාමාන්‍යයෙන් best # පරීක්ෂා කිරීම වඩාත් සුදුසුය, එය තර්ක ගණන වන මගේ මතයයි.

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

1
පළමු පරීක්ෂණය පසුගාමී ය; මම හිතන්නේ ඔබට අවශ්‍යයි [ "$1" != "" ](හෝ [ -n "$1" ]) ...
ගෝර්ඩන් ඩේවිසන්

10
$1හිස් නූලට සකසා ඇත්නම් මෙය අසාර්ථක වේ.
HelloGoodbye

2
පිළිතුරේ දෙවන කොටස (පරාමිති ගණන් කිරීම) $1හිස් නූලකට සකසා ඇති විට පිළිතුරේ පළමු කොටස ක්‍රියා නොකිරීම සඳහා ප්‍රයෝජනවත් ක්‍රියාමාර්ගයකි .
මාර්ක් බෙරී

සක්‍රිය නම් මෙය අසාර්ථක වනු set -o nounsetඇත.
Flimm

22

සටහන

bashටැගය නිසා මම දැඩි ලෙස අවධානය යොමු කළ පිළිතුරක් ලබා දෙමි .

කෙටි පිළිතුර

ඔබ Bash හි නම් කරන ලද විචල්‍යයන් සමඟ පමණක් කටයුතු කරන තාක් කල්, මෙම ශ්‍රිතය සෑම විටම ඔබට කියනුයේ විචල්‍යය සකසා ඇත්ද, එය හිස් අරාවක් වුවද.

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

මෙය ක්‍රියාත්මක වන්නේ ඇයි?

Bash හි (අවම වශයෙන් 3.0 තරම් back varත ), ප්‍රකාශිත / සැකසුම් විචල්‍යයක් නම්, එහි වර්තමාන වර්ගය සහ අගය කුමක් වුවත් විචල්‍යයක් declare -p varසැකසෙන declareවිධානයක් ප්‍රතිදානය කර varතත්ව කේතය 0(සාර්ථකත්වය) ලබා දෙයි. ප්‍රකාශයට පත් නොකළේ නම් var, declare -p varදෝෂ පණිවිඩයක් ප්‍රතිදානය කර stderrතත්ව කේතය ලබා දෙයි 1. තත්ව කේතය වෙනස් නොකර, භාවිතා කිරීම &>/dev/null, නිත්‍ය stdoutසහ stderrප්‍රතිදානය යන දෙකටම නැවත යොමු /dev/nullකරයි. මේ අනුව ශ්‍රිතය නැවත ලබා දෙන්නේ තත්ව කේතය පමණි.

Bash හි වෙනත් ක්‍රම (සමහර විට) අසමත් වීමට හේතුව

  • [ -n "$var" ]: මෙය පරික්ෂා කරන්නේ ${var[0]}නොසැලකිලිමත් නම් පමණි . (Bash හි, $varසමාන වේ ${var[0]}.)
  • [ -n "${var+x}" ]: මෙය පරික්ෂා කරන්නේ ${var[0]}සකසා ඇත්නම් පමණි .
  • [ "${#var[@]}" != 0 ]: මෙය පරික්ෂා කරන්නේ අවම වශයෙන් එක් දර්ශකයක්වත් $varසකසා ඇත්නම් පමණි .

මෙම ක්‍රමය Bash හි අසමත් වූ විට

මෙම පමණක් නම් විචල්යයන් (ඇතුළු සඳහා ක්රියා $_), නො යම් යම් විශේෂ විචල්යයන් ( $!, $@, $#, $$, $*, $?, $-, $0, $1, $2, ..., ඕනෑම මම අමතක විය හැක). මේ කිසිවක් අරා නොවන බැවින්, මෙම [ -n "${var+x}" ]සියලු විශේෂ විචල්‍යයන් සඳහා පොසික්ස් විලාසිතාව ක්‍රියා කරයි. බොහෝ විශේෂ විචල්‍යයන් ශ්‍රිතයන් හැඳින්වෙන විට අගයන් / පැවැත්ම වෙනස් කරන බැවින් එය ශ්‍රිතයක් තුළට ඔතා පරිස්සම් වන්න.

ෂෙල් අනුකූලතා සටහන

ඔබේ ස්ක්‍රිප්ටයේ අරා තිබේ නම් සහ ඔබ එය හැකි තරම් ෂෙල් වෙඩි සමඟ අනුකූල කිරීමට උත්සාහ කරන්නේ නම්, ඒ typeset -pවෙනුවට භාවිතා කිරීම ගැන සලකා බලන්න declare -p. Ksh කලින් සහාය දෙන බව මම කියවා ඇත්තෙමි, නමුත් මෙය පරීක්ෂා කිරීමට නොහැකි විය. මම එක් එක් උපකාරක දන්නේ බව බෑෂ් 3.0+ සහ Zsh 5.5.1 දෙකම typeset -pහා declare -p, පමණක් වන එක් අනෙක් සඳහා විකල්ප වේ වෙනස්. නමුත් මම එම මූල පද දෙකෙන් ඔබ්බට වෙනස්කම් පරීක්ෂා කර නැති අතර වෙනත් ෂෙල් වෙඩි පරීක්ෂා කර නැත.

ඔබේ ස්ක්‍රිප්ටය POSIX sh අනුකූල වීමට අවශ්‍ය නම්, ඔබට අරා භාවිතා කළ නොහැක. අරා නොමැතිව, [ -n "{$var+x}" ]ක්රියා කරයි.

Bash හි විවිධ ක්‍රම සඳහා සංසන්දනාත්මක කේතය

මෙම ශ්‍රිතය විචල්යය var, evalසම්මත කළ කේතය, d කේතය varමඟින් සකසා තිබේද යන්න තීරණය කිරීම සඳහා පරීක්ෂණ ධාවනය කරයි eval, අවසානයේදී විවිධ පරීක්ෂණ සඳහා ප්‍රති ing ල ලැබෙන තත්ව කේත පෙන්වයි.

මම පනින කරනවා test -v var, [ -v var ]සහ [[ -v var ]]ඔවුන් POSIX සම්මත සමාන ප්රතිඵල නිසා [ -n "${var+x}" ]බෑෂ් 4.2+ අවශ්ය අතර,. මම පරීක්‍ෂා කළ ෂෙල් වෙඩි typeset -pහා සමාන බැවින් මම ද මඟ declare -pහරිමි (Bash 3.0 thru 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
}

සිද්ධි කේතය පරීක්ෂා කරන්න

විචල්‍යය සහායක අරාව ලෙස ප්‍රකාශයට පත් කර නොමැති නම්, සංඛ්‍යාත්මක නොවන අරාව දර්ශක "0" ලෙස Bash සැලකීම නිසා පරීක්ෂණ ප්‍රති results ල අනපේක්ෂිත විය හැකි බව සලකන්න. තවද, සහායක අරා වලංගු වන්නේ 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

පරීක්ෂණ ප්‍රතිදානය

කිරීම සදහා ශීර්ෂ පේළිය අනුරූප දී ටෙස්ට් mnemonics [ -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 ස්ක්‍රිප්ට් සඳහා සුදුසු නොවේ.

3
මා උත්සාහ කළ පිළිතුරු අතුරින්, මෙය ( declare -p var &>/dev/null) ක්‍රියාත්මක වන්නේ එකම එකකි. ඔබට ස්තුතියි!
user1387866

2
@ මම එය කියවන එසේ ඔබේ පිළිතුර ඔබේ කාර්යය කේතය කිරීමට පෙර "/" තීරනාත්මක එකතු කිරීමට සංස්කරණය කිරීමට උත්සාහ ලකුණ-haferkamp ... &> /dev/nullපවා සුදු-අවකාශය එකතු උත්සාහ - එහෙත් SO මා තනි චරිතය සංස්කරණය කරන්න 🙄 ඉඩ දුන්නේ නෑ (විය යුතුය> අකුරු 6 නමුත් එය ක්‍රියාත්මක වූයේ නැත). එසේම, ඔබ පෙන්වා දුන් පරිදි, $1විචල්ය (උදා OUTPUT_DIR) නම් නියැදියක් සඳහා මාරුවීම සඳහා කාර්යය වෙනස් කිරීම වටී $1. කෙසේ වෙතත්, එය තීරණාත්මක සංස්කරණයකි, එසේ නොමැතිනම් කේතය nullසාපේක්ෂ නාමාවලියක නමින් ගොනුවක් සෑදීමට බලාපොරොත්තු වේ dev. BTW - නියම පිළිතුර!
joehanna

එසේම, $ උපසර්ගය නොමැතිව විචල්ය නාමය භාවිතා ද ක්රියා කරයි: declare -p PATH &> /dev/nullප්රතිලාභ 0 එහිදී ලෙස declare -p ASDFASDGFASKDF &> /dev/nullප්රතිලාභ 1. (bash 5.0.11 (1) මත -release)
joehanna

1
නියම වැඩක්! අවවාදය 1 වචනය: declare varvar විචල්ය ප්රකාශ නමුත් එය කරන්නේ නැහැ අනුව එය සකස් set -o nounset: ටෙස්ට් ක්රිකට්declare foo bar=; set -o nounset; echo $bar; echo $foo
xebeche

අතුරුදහන් වීම අල්ලා ගැනීම ගැන ස්තූතියි /! මම එය නිවැරදි කළෙමි, නමුත් මම සිතන්නේ තර්කනය ශ්‍රිතයක් සඳහා ප්‍රමාණවත් තරම් ව්‍යාකූල වන බවයි, විශේෂයෙන් @ xebeche ගේ ප්‍රකාශය අනුව. @xebeche එය මගේ පිළිතුරට අපහසුයි… මට පෙනෙන ආකාරයට declare -p "$1" | grep =හෝ යමක් උත්සාහ කිරීමට සිදුවේ test -v "$1".
මාර්ක් හැෆර්කැම්ප්

20

ස්ක්‍රිප්ටයක සිටින විට සැකසූ හෝ හිස් දැයි පරීක්ෂා කිරීමට බලාපොරොත්තු වන අය සඳහා set -u:

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

නිත්ය [ -z "$var" ]චෙක්පත සමඟ අසාර්ථක වනු ඇත var; unbound variableනම් set -uනමුත් [ -z "${var-}" ] පුළුල් නම් හිස් අගයක් කිරීමට varඅසමත් වීම තොරව ශූන්යය වේ.


ඔබට මහා බඩවැලක් නොමැත. එය විය යුතු ${var:-}නොවේ ${var-}. නමුත් බාෂ්හිදී, එය මහා බඩවැල් නොමැතිව පවා ක්‍රියාත්මක වන බව මට තහවුරු කළ හැකිය.
පලෙක්

5
${var:-}සහ ${var-}විවිධ දේ අදහස් කරන්න. ${var:-}නම් හිස් අගයක් වන පරිදි පුළුල් කරනු ලබනවා varශූන්යය හෝ ශූන්ය හා ${var-}එකම ශූන්යය නම් string හිස් කිරීමට පුළුල් වනු ඇත.
රූබන් ලගූනා

අලුත් දෙයක් ඉගෙන ගත්තා, ස්තූතියි! මහා බඩවැලෙන් ඉවත්වීම මඟින් පරීක්ෂණයකට භාජනය වන්නේ සැකසූ පරාමිතියක් සඳහා පමණි. තවත් ක්‍රමයක් තබන්න, මහා බඩවැල ඇතුළත් කර ඇත්නම්, ක්‍රියාකරු පරාමිතියේ පැවැත්ම සහ එහි වටිනාකම අහෝසි නොවන බව පරීක්ෂා කරයි; මහා බඩවැල මඟ හැරී ඇත්නම්, ක්‍රියාකරු පරීක්‍ෂා කරන්නේ පැවැත්ම සඳහා පමණි. එය මෙහි කිසිදු වෙනසක් නොකරයි, නමුත් දැන ගැනීම හොඳය.
Palec

17

එය සකසා නොමැති නම් ඔබට පිටවීමට අවශ්‍යය

මෙය මට වැඩ කළා. පරාමිතියක් සකසා නොමැතිනම් දෝෂ සහිත පණිවිඩයක් සමඟ මගේ පිටපත පිටවීමට මට අවශ්‍ය විය.

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

පරීක්ෂා කිරීම පමණි, පිටවීමක් නැත - හිස් සහ අස්ථාපනය අවලංගුය

අගය = VALID හෝ unset / හිස් = INVALID අගය පරීක්ෂා කිරීමට ඔබට අවශ්‍ය නම් මෙම විකල්පය උත්සාහ කරන්න.

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 = VALID හෝ unset = INVALID අගය සකසා ඇත්දැයි පරීක්ෂා කිරීමට අවශ්‍ය නම් මෙය භාවිතා කරන්න.

සටහන, "..- 1 in" හි "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 (අදහස්) සඳහා මම කැප කරමි.

යොමුව http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02


15

හිස් නොවන අගයකින් විචල්‍යයක් සකසා ඇත්දැයි පරීක්ෂා කිරීමට [ -n "$x" ], අනෙක් අය දැනටමත් පෙන්වා දී ඇති පරිදි භාවිතා කරන්න .

බොහෝ විට, හිස් අගයක් ඇති විචල්‍යයකට සැකසූ විචල්‍යයකට සමාන ආකාරයකින් සැලකීම හොඳ අදහසකි. ඔබට අවශ්‍ය නම් මේ දෙක වෙන්කර හඳුනාගත හැකිය: [ -n "${x+set}" ]( සකසා "${x+set}"තිබේ setනම් xසහ සැකසූ විට හිස් xනූල දක්වා පුළුල් වේ).

පරාමිතියක් සම්මත වී ඇත්දැයි පරීක්ෂා කිරීම සඳහා, පරීක්‍ෂණය කරන්න $#, එය ශ්‍රිතයට ලබා දුන් පරාමිති ගණන (හෝ ශ්‍රිතයක නොමැති විට ස්ක්‍රිප්ටයට) ( පාවුල්ගේ පිළිතුර බලන්න ).


14

bashමෑන් පිටුවේ "පරාමිති පුළුල් කිරීම" කොටස කියවන්න . පරාමිති ප්‍රසාරණය විචල්‍යයක් සැකසීමට සාමාන්‍ය පරීක්ෂණයක් සපයන්නේ නැත, නමුත් එය සකසා නොමැති නම් පරාමිතියකට ඔබට කළ හැකි කරුණු කිහිපයක් තිබේ.

උදාහරණයක් වශයෙන්:

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

සකස් කරනු ඇත first_argසමාන $1ආකාරයකින් එය අගය "foo" භාවිතා කරයි, එය අනුයුක්ත කර ඇත නම්. නම් aපරම තනි පරාමිතිය ගත යුතුය, කිසිදු යහපත් පෙරනිමි පවතී, නැහැ, ඔබ පරාමිතිය දෙන විට දෝෂයක් පණිවිඩය සමග එලියට ආ හැක:

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

( :ශුන්‍ය විධානයක් ලෙස භාවිතා කිරීම සැලකිල්ලට ගන්න , එය එහි තර්කවල අගයන් පුළුල් කරයි. $1මෙම උදාහරණයෙන් අපට කිසිවක් කිරීමට අවශ්‍ය නැත , එය සකසා නොමැතිනම් පිටවන්න)


1
අනෙක් පිළිතුරු කිසිවක් සරල හා අලංකාර ලෙස සඳහන් නොකිරීම මට කරදරයකි : ${var?message}.
ත්‍රිත්ව

ඔබ මෙය ගත්තේ කොහෙන්ද? පුදුමාකාරයි! ඒක වැඩ කරනවා! එය කෙටි හා අලංකාරයි! ඔබට ස්තුතියි!
රොජර්

13

බාෂ් තුළ ඔබට බිල්ටින් -vතුළ භාවිතා කළ හැකිය [[ ]]:

#! /bin/bash -u

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

echo $SOMEVAR

8

භාවිතා කිරීම [[ -z "$var" ]]යනු විචල්‍යයක් සකසා තිබේද නැද්ද යන්න දැන ගැනීමට ඇති පහසුම ක්‍රමයයි, නමුත් එම විකල්පය -zසැකසූ විචල්‍යයක් සහ විචල්‍ය කට්ටලයක් හිස් නූලකට වෙන්කර හඳුනා නොගනී:

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

විචල්ය වර්ගය අනුව එය පරීක්ෂා කිරීම වඩාත් සුදුසුය: env විචල්‍යය, පරාමිතිය හෝ නිත්‍ය විචල්‍යය.

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කේතයට බලපෑමක් නොකර ප්‍රතිදානය මර්දනය කරයි.

5

Bash විකල්පය set -uසක්‍රිය කර ඇති විට ඉහත පිළිතුරු ක්‍රියා නොකරයි . එසේම, ඒවා ගතික නොවේ, උදා: "ව්‍යාජ" නම සමඟ විචල්‍ය වන්නේ කෙසේද යන්න නිර්වචනය කර ඇත්තේ කෙසේද? මේක උත්සාහ කරන්න:

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" ආකාරයෙන් අර්ථ දක්වා තිබේදැයි පරීක්ෂා කරන්නේ කෙසේද?


1
මෙම පිළිතුර පහත් කොට සැලකීමට හේතුව දැන ගැනීමට මා කැමතිය ... මට හොඳට වැඩ කරයි.
LavaScornedOven

Bash හි, ඔබට එවාල් නොමැතිව එය කළ හැකිය: eval "[ ! -z \${$1:-} ]"වක්‍ර ඇගයීමකට වෙනස් කිරීම : [ ! -z ${!1:-} ];.

InaryBinaryZebra: සිත්ගන්නා අදහස. වෙනම පිළිතුරක් ලෙස පළ කිරීමට මම යෝජනා කරමි.
kevinarpe

"Ev" භාවිතා කිරීමෙන් මෙම විසඳුම කේත එන්නත් කිරීමට ගොදුරු වේ: $ is_var_defined 'x}]; echo "gotcha"> & 2; # '
ගොචා

4

ඔබට කළ හැකිය:

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

9
එසේත් නැතිනම් ඔබට එය කළ -nනොහැකිය -z.
වැඩිදුර දැනුම් දෙන තුරු විරාමය.

1
ඔබට වටා උපුටා දැක්වීම් අවශ්‍යයි $1, එනම් [ ! -z "$1" ]. නැතහොත් ඔබට [[ ! -z $1 ]]bash / ksh / zsh වලින් ලිවිය හැකිය .
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

5
$1හිස් නූලට සකසා ඇත්නම් මෙය අසාර්ථක වේ.
HelloGoodbye

4

මගේ ප්‍රියතම ක්‍රමය මෙයයි:

$ 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

එබැවින් මූලික වශයෙන්, විචල්යයක් සකසා ඇත්නම්, එය "ප්රති ing ලයක් ලෙස ප්රතික්ෂේප කිරීමක්" බවට පත්වේ false(කුමක් වනු ඇත්ද true= "සකසා ඇත්තේ").

තවද, එය සකසා නොමැති නම්, එය "ප්‍රති trueresult ලයක් ලෙස ප්‍රතික්ෂේප කිරීමක්" බවට පත්වනු ඇත (හිස් ප්‍රති result ලය තක්සේරු කරන පරිදි true) (එබැවින් අවසන් වන්නේ false= "සකසා නැත").



1

ෂෙල් එකක ඔබට -zනූල් වල දිග ශුන්‍ය නම් සත්‍ය වන ක්‍රියාකරු භාවිතා කළ හැකිය .

MY_VARඑය සකසා නොමැති නම් පෙරනිමිය සැකසීමට සරල එක්-ලයිනර් , නැතිනම් විකල්පයක් ලෙස ඔබට පණිවිඩය පෙන්විය හැකිය:

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

0
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi

if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi

$1, $2සහ දක්වා $Nසෑම විටම සකසා ඇත. කණගාටුයි, මෙය අසාර්ථකයි.

මම එය අත්හදා බැලුවෙමි, නමුත් එය ක්‍රියාත්මක වූයේ නැත, සමහර විට මගේ බෑෂ් අනුවාදයට ඒ සඳහා සහය නොලැබේ. ඉඩ්ක්, සමාවෙන්න මම වැරදියි නම්. :)

0

ඔබට ඕනෑම දෙයක් පරීක්ෂා කිරීමට අවශ්‍ය නම් මෙය කිරීමට වඩා හොඳ (වඩා) කේතයක් මට හමු විය $@.

[[$ 1 = ""]] නම්
එවිට
  echo '$ 1 හිස්'
නැතිනම්
  echo '$ 1 පුරවා ඇත'
fi

ඇයි මේ සියල්ල? සෑම දෙයක්ම $@බෑෂ් දී පවතී, නමුත් පෙරනිමියෙන් එය එසේ, හිස් දෙයක් test -zහා test -nඔබ කර ගත නොහැකි විය.

යාවත්කාලීන කිරීම: ඔබට පරාමිතීන්හි අක්ෂර ගණන ගණනය කළ හැකිය.

[$ {# 1} = 0] නම්
එවිට
  echo '$ 1 හිස්'
නැතිනම්
  echo '$ 1 පුරවා ඇත'
fi

මම දන්නවා, නමුත් එපමණයි. යමක් හිස් නම් ඔබට දෝෂයක් ලැබෙනු ඇත! සමාවන්න. : P

0
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi

11
StackOverflow වෙත සාදරයෙන් පිළිගනිමු. ඔබේ පිළිතුර අගය කරන අතරම, කේතයට වඩා වැඩි යමක් දීම වඩාත් සුදුසුය. ඔබේ පිළිතුරට හෝ කුඩා පැහැදිලි කිරීමකට තර්කානුකූලව එකතු කළ හැකිද? ඔබේ පිළිතුර පුළුල් කිරීම පිළිබඳ වෙනත් අදහස් සඳහා මෙම පිටුව බලන්න .
සෙලියෝ

0

මම දිනපතා භාවිතා කරන්නේ මෙයයි:

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

මෙය ලිනක්ස් සහ සොලාරිස් යටතේ බාෂ් 3.0 දක්වා හොඳින් ක්‍රියා කරයි.

bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1

1
Bash 2.0+ වක්‍ර ප්‍රසාරණය ලබා ගත හැකි බැවින්. ඔබට සමාන දිගු හා සංකීර්ණ (එවාල් ද ඇතුළත්) test -n "$(eval "echo "\${${1}+x}"")"ආදේශ කළ හැකිය:[[ ${!1+x} ]]

0

බාෂ් හි ගොරහැඩි තොරතුරු සැඟවීමට මම සහායක කාර්යයන් වලට කැමතියි. මෙම අවස්ථාවේ දී, එසේ කිරීමෙන් ඊටත් වඩා (සැඟවුණු) රළුබවක් එක් කරයි:

# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
  local varname="$1"
  ! [ -z ${!varname+x} ]
}

මෙම ක්‍රියාවට නැංවීමේදී මට මුලින්ම දෝෂ ඇති වූ නිසා (ජෙන්ස් සහ ලයනල්ගේ පිළිතුරු වලින් ආනුභාව ලත්), මම වෙනස් විසඳුමක් ඉදිරිපත් කළෙමි:

# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
  declare -p $1 &>/dev/null
}

එය වඩාත් forward ජුව ඉදිරියට යන, වඩා අවුල් සහගත සහ තේරුම් ගැනීමට / මතක තබා ගැනීමට පහසු බව මට පෙනේ. පරීක්ෂණ නඩුව එය සමාන බව පෙන්වයි:

function main()
{
  declare -i xyz
  local foo
  local bar=
  local baz=''

  IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
  IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
  IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
  IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"

  IsDeclared xyz; echo "IsDeclared xyz: $?"
  IsDeclared foo; echo "IsDeclared foo: $?"
  IsDeclared bar; echo "IsDeclared bar: $?"
  IsDeclared baz; echo "IsDeclared baz: $?"
}

main

පරීක්ෂණ නඩුව දර්ශන ද local varනැත නොවේ ( '=' විසින් අනුගමනය නම්) var ප්රකාශ කරනවා. සෑහෙන කාලයක් තිස්සේ මම සිතුවේ මම මේ ආකාරයෙන් විචල්‍යයන් ප්‍රකාශයට පත් කළ බවයි, දැන් මගේ අභිප්‍රාය ප්‍රකාශ කර ඇති බව දැන ගැනීම සඳහා ... එය කිසිසේත්ම විකල්පයක් නොවන බව මම අනුමාන කරමි.

IsDeclared_Tricky xyz: 1
IsDeclared_Tricky foo: 1
IsDeclared_Tricky bar: 0
IsDeclared_Tricky baz: 0
IsDeclared xyz: 1
IsDeclared foo: 1
IsDeclared bar: 0
IsDeclared baz: 0 Is

බෝනස්: භාවිතා කරන්න

මම බොහෝ දුරට මෙම පරීක්ෂණය භාවිතා කරන්නේ තරමක් "අලංකාර" සහ ආරක්ෂිත ආකාරයකින් (අතුරු මුහුණතක් හා සමානයි ...) කාර්යයන් සඳහා පරාමිතීන් ලබා දීමට (සහ ආපසු ).

#auxiliary functions
function die()
{
  echo "Error: $1"; exit 1
}

function assertVariableDeclared()
{
  IsDeclared "$1" || die "variable not declared: $1"
}

function expectVariables()
{
  while (( $# > 0 )); do
    assertVariableDeclared $1; shift
  done
}

# actual example
function exampleFunction()
{
  expectVariables inputStr outputStr
  outputStr="$inputStr world!"
}

function bonus()
{
  local inputStr='Hello'
  local outputStr= # remove this to trigger error
  exampleFunction
  echo $outputStr
}

bonus

සියල්ල සමඟ කැඳවනු ලැබුවහොත් ප්‍රකාශිත විචල්‍යයන් අවශ්‍ය වේ:

හෙලෝ වර්ල්ඩ්!

වෙනත්:

දෝෂය: විචල්‍යය ප්‍රකාශ කර නැත: outputStr


0

සියලුම පිළිතුරු මග හැරීමෙන් පසුව, මෙයද ක්‍රියාත්මක වේ:

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එය දැමුවේ නැත්නම්, එය හිස් අගයකට සකසනු ඇත; $මෙය ක්‍රියාත්මක වීමට අවශ්‍ය වේ.


දෝෂය set -uමුද්‍රණය කරන ඔබ ක්‍රියාත්මක වන විට ක්‍රියා නොකරනු ඇතunboud variable
මයිකල් හියුබර්ජර්

0

සාරාංශය

  • test -n "${var-}"විචල්‍යය හිස් නොවේ දැයි පරීක්ෂා කිරීමට භාවිතා කරන්න (එබැවින් අර්ථ දැක්විය යුතුය / සැකසිය යුතුය)
  • test ! -z "${var+}"විචල්‍යය නිර්වචනය කර ඇත්දැයි පරීක්ෂා කිරීමට භාවිතා කරන්න (එය හිස් වුවත්)

පළමු භාවිත අවස්ථාව ෂෙල් ස්ක්‍රිප්ට් වල බහුලව දක්නට ලැබෙන අතර මෙය ඔබට සාමාන්‍යයෙන් භාවිතා කිරීමට අවශ්‍ය වනු ඇත.

සටහන්

  • මෙම විසඳුම සියලුම පොසික්ස් ෂෙල් වෙඩි (sh, bash, zsh, ksh, dash) තුළ ක්‍රියා කළ යුතුය.
  • මෙම ප්‍රශ්නයට තවත් පිළිතුරු සමහරක් නිවැරදි නමුත් ෂෙල් ස්ක්‍රිප්ටින් පිළිබඳ අද්දැකීම් අඩු අයට එය ව්‍යාකූල විය හැකිය, එබැවින් මට අවශ්‍ය වූයේ එවැනි පුද්ගලයින් සඳහා අවම වශයෙන් ව්‍යාකූල වන TLDR පිළිතුරක් ලබා දීමට ය.

පැහැදිලි කිරීම

මෙම විසඳුම ක්‍රියාත්මක වන ආකාරය තේරුම් ගැනීමට, ඔබ POSIX testවිධානය සහ POSIX shell පරාමිති ප්‍රසාරණය ( පිරිවිතර ) තේරුම් ගත යුතුය, එබැවින් පිළිතුර තේරුම් ගැනීමට අවශ්‍ය නිරපේක්ෂ මූලික කරුණු ආවරණය කරමු.

පරීක්ෂණ විධානය මඟින් ප්‍රකාශනයක් තක්සේරු කර සත්‍ය හෝ අසත්‍යය ලබා දෙයි (එහි පිටවීමේ තත්වය හරහා). -nඔපෙරන්ඩ් හිස් නොවන නූලක් නම් ක්‍රියාකරු සත්‍ය වේ. උදාහරණයක් ලෙස, test -n "a"සත්‍යය test -n ""නැවත ලබා දෙන අතර අසත්‍යය නැවත ලබා දේ. දැන්, විචල්‍යයක් හිස් නොවේ දැයි පරීක්ෂා කිරීමට (එයින් අදහස් වන්නේ එය අර්ථ දැක්විය යුතු බවයි), ඔබට භාවිතා කළ හැකිය test -n "$var". කෙසේ වෙතත්, සමහර ෂෙල් ස්ක්‍රිප්ට් වලට විකල්ප කට්ටලයක් ඇත ( set -u) එය නිර්වචනය නොකළ විචල්‍යයන් පිළිබඳ කිසියම් සඳහනක් දෝෂයක් විමෝචනය කරයි, එබැවින් විචල්‍යය varනිර්වචනය නොකළහොත් ප්‍රකාශනය $aදෝෂයක් ඇති කරයි. මෙම නඩුව නිවැරදිව හැසිරවීමට, ඔබ විචල්ය ප්‍රසාරණය භාවිතා කළ යුතු අතර, එමඟින් විචල්‍යය නිර්වචනය කර නොමැති නම් විකල්ප නූලක් සමඟ ප්‍රතිස්ථාපනය කිරීමට කවචයට කියනු ඇත, ඉහත සඳහන් දෝෂය වළක්වා ගන්න.

විචල්ය ප්‍රසාරණය ${var-}යන්නෙන් අදහස් වන්නේ: විචල්‍යය varනිර්වචනය කර නොමැති නම් ("සැකසූ" ලෙසද හැඳින්වේ), එය හිස් නූලකින් ආදේශ කරන්න. ඒ නිසා test -n "${var-}"නම් සැබෑ ආපසු $varඔබ ෂෙල් ස්ක්රිප්ට් පරික්ෂා කිරීමට අවශ්ය දේ සෑම විටම පාහේ වන, හිස් නොවේ. ප්‍රතිලෝම චෙක්පත $varනිර්වචනය කර නොමැති නම් හෝ හිස් නොවේ නම් test -z "${var-}".

දැන් දෙවන භාවිත අවස්ථාව වෙත: විචල්‍යය varනිර්වචනය කර ඇත්දැයි පරීක්ෂා කිරීම හිස්ද නැද්ද යන්න පරීක්ෂා කිරීම . මෙය අඩු පොදු භාවිතයක් වන අතර තරමක් සංකීර්ණ වන අතර එය වඩා හොඳින් අවබෝධ කර ගැනීම සඳහා ලයනල්ගේ විශිෂ්ට පිළිතුර කියවීමට මම ඔබට උපදෙස් දෙමි .


-1

Var එකක් සකසා තිබේද නැද්ද යන්න පරීක්ෂා කිරීම

var=""; [[ $var ]] && echo "set" || echo "not set"

3
$varහිස් නූලට සකසා ඇත්නම් මෙය අසාර්ථක වේ.
HelloGoodbye

-1

විචල්‍යයක් බැඳී හෝ අසීමිත දැයි පරීක්ෂා කිරීමට ඔබට අවශ්‍ය නම්, ඔබ නාම පද විකල්පය සක්‍රිය කිරීමෙන් පසුව පවා මෙය හොඳින් ක්‍රියාත්මක වේ:

set -o noun set

if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi

මම හිතන්නේ ඔබ අදහස් කළේ set -o nounset, නැත set -o noun set. මෙය ක්‍රියාත්මක වන්නේ exportසංස්කරණය කර ඇති විචල්‍යයන් සඳහා පමණි . එය ඔබගේ සැකසීම් අහෝසි කිරීමට අපහසු ආකාරයකින් වෙනස් කරයි.
කීත් තොම්සන්
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.