පෙරවදන
පළමුව, මම කියන්නේ ගැටලුව විසඳීමට එය නිවැරදි ක්රමය නොවන බවයි. එය හරියට " ඔබ මිනිසුන් murder ාතනය නොකළ යුතු නිසා වෙනත් ආකාරයකින් ඔබ හිරේට යනු ඇත " යනුවෙන් පැවසීම වැනි ය .
ඒ හා සමානව, ඔබ ඔබේ විචල්යය උපුටා දක්වන්නේ නැත, එසේ නොමැතිනම් ඔබ ආරක්ෂක දුර්වලතා හඳුන්වා දෙයි. ඔබ ඔබේ විචල්යයන් උපුටා දක්වන්නේ එය වැරදියි (නමුත් සිරගෙදරට ඇති බිය උපකාර විය හැකි නම්, එසේ නොවන්නේ මන්ද).
දුම්රියට පැන ඇති අය සඳහා කුඩා සාරාංශයක්.
බොහෝ කවච වල, විචල්ය ප්රසාරණයක් නම් නොකොට තැබීම (එය (සහ මෙම පිළිතුරේ ඉතිරි කොටස) විධාන ආදේශනයට ( `...`
හෝ $(...)
) අදාළ වන අතර අංක ගණිත ප්රසාරණයට ( $((...))
හෝ $[...]
) විශේෂ අර්ථයක් ඇත. එය විස්තර කිරීමට ඇති හොඳම ක්රමය නම් එය යම් ආකාරයක ව්යංග භේදයක් + ග්ලෝබ් ක්රියාකරුට ආයාචනා කිරීමයි.
cmd $var
වෙනත් භාෂාවකින් මෙසේ ලියනු ඇත:
cmd(glob(split($var)))
$var
$IFS
විශේෂ පරාමිතිය ( බෙදීම් කොටස) සම්බන්ධ සංකීර්ණ නීතිරීතිවලට අනුව පළමුව වචන ලැයිස්තුවකට බෙදනු ලබන අතර , එම බෙදීමේ ප්රති result ලයක් ලෙස ඇති වන සෑම වචනයක්ම එයට ගැලපෙන ලිපිගොනු ලැයිස්තුවකට ( ගෝලීය කොටස) පුළුල් වන රටාවක් ලෙස සැලකේ. .
නිදසුනක් ලෙස, $var
අඩංගු නම් *.txt,/var/*.xml
සහ $IFS
අඩංගු නම් ,
, cmd
තර්ක ගණනාවක් සමඟ කැඳවනු ලැබේ, පළමුවැන්න cmd
සහ ඊළඟ ඒවා txt
වත්මන් නාමාවලියෙහි ඇති xml
ලිපිගොනු සහ ඇති ගොනු ය /var
.
ඔබට cmd
වචනානුසාරයෙන් තර්ක දෙකකින් ඇමතීමට අවශ්ය නම් cmd
සහ *.txt,/var/*.xml
ඔබ ලියන්නේ:
cmd "$var"
එය ඔබගේ අනෙක් හුරුපුරුදු භාෂාවෙන් වනු ඇත:
cmd($var)
කවචයක ඇති අවදානම යන්නෙන් අප අදහස් කරන්නේ කුමක්ද?
ආරක්ෂිත සංවේදී සන්දර්භයන් තුළ ෂෙල් ස්ක්රිප්ට් භාවිතා නොකළ යුතු බව කාලයාගේ ඇවෑමෙන් දැනගෙන තිබේ. නිසැකවම, හරි, විචල්යයක් සඳහන් නොකිරීම දෝෂයකි, නමුත් එතරම් හානියක් කළ නොහැකිද?
හොඳයි, වෙබ් සීජීඅයි සඳහා කවදාවත් ෂෙල් ස්ක්රිප්ට් භාවිතා නොකළ යුතු යැයි කිසිවෙකු ඔබට පැවසුවද, හෝ ස්තුතිවන්ත විය යුතු බොහෝ පද්ධති වර්තමානයේදී සෙටූයිඩ් / සෙට්ජිඩ් ෂෙල් ස්ක්රිප්ට් වලට ඉඩ නොදේ. ෂෙල්ෂොක් (දුරස්ථව සූරාකෑමට ලක්වන බාෂ් දෝෂය 2014 සැප්තැම්බර් මාසයේ දී සිරස්තල) අනාවරණය ෂෙල් වෙඩි තවමත් පුළුල් ඔවුන් බොහෝ විට නොවිය යුතු තැන භාවිතා කරන බව ය: පළ කළහ sudoers විධානයන් DHCP ග්රාහකයක් කොක්කෙන් පිටපත් ද,, CGIs දී විසින් (නොවේ නම් ලෙස ) setuid විධාන ...
සමහර විට නොදැනුවත්ව. උදාහරණයක් ලෙස system('cmd $PATH_INFO')
දී php
/ perl
/ python
CGI විධානාවලිය විධාන රේඛාව (සඳහන් නොකලත් බව අර්ථ නිරූපණය කිරීමට තිබෙන shell පහ කරන්නේ cmd
ම ෂෙල් තිර රචනය සහ එහි කර්තෘ විය හැක එය ලබන්නේ CGI කැඳවා කිරීමට අපේක්ෂා කවදාවත් ඇත).
වරප්රසාද ඉහළ නැංවීමේ මාර්ගයක් ඇති විට ඔබට අවදානමක් තිබේ, එනම් යමෙකුට (ඔහුට පහර දෙන්නා යැයි කියමු ) ඔහු අදහස් නොකරන දෙයක් කිරීමට හැකි වේ.
නොවරදවාම එයින් අදහස් කරන්නේ දත්ත සපයන ප්රහාරකයා , වරප්රසාදිත පරිශීලකයෙකු / ක්රියාවලියක් විසින් දත්ත සැකසීම, එය නොදැනුවත්වම එය නොකළ යුතු දෙයක් කරන අතර, බොහෝ විට එය දෝෂයක් නිසා ය.
මූලික වශයෙන්, ඔබේ දෝෂ සහිත කේතය ප්රහාරකයාගේ පාලනය යටතේ දත්ත සැකසීමේදී ඔබට ගැටළුවක් ඇත.
දැන්, එම දත්ත පැමිණෙන්නේ කොහෙන්ද යන්න සැමවිටම පැහැදිලිව පෙනෙන්නට නැති අතර, විශ්වාසනීය නොවන දත්ත සැකසීමට ඔබේ කේතය කවදා හෝ ලැබේදැයි කීමට බොහෝ විට අපහසුය.
විචල්යයන් සම්බන්ධයෙන් ගත් කල, සීජීඅයි ස්ක්රිප්ටයක් සම්බන්ධයෙන් ගත් කල, දත්ත පැහැදිලිවම සීජීඅයි ජීඊටී / පෝස්ට් පරාමිතීන් සහ කුකීස්, පථය, ධාරක ... පරාමිතීන් ය.
සෙටූයිඩ් ස්ක්රිප්ටයක් සඳහා (එක් පරිශීලකයෙකු වෙනත් අයෙකු විසින් ක්රියාත්මක කරන විට), එය තර්ක හෝ පරිසර විචල්යයන් වේ.
තවත් ඉතා සුලභ දෛශිකයක් වන්නේ ගොනු නම් ය. ඔබ නාමාවලියකින් ගොනු ලැයිස්තුවක් ලබා ගන්නේ නම්, ප්රහාරකයා විසින් එහි ලිපිගොනු රෝපණය කර ඇති බව පෙනේ.
මේ සම්බන්ධයෙන්, අන්තර්ක්රියාකාරී කවචයක කඩිනමින් වුවද, ඔබ අවදානමට ලක්විය හැකිය (ලිපිගොනු සැකසීමේදී /tmp
හෝ ~/tmp
උදාහරණයක් ලෙස).
පවා ~/.bashrc
අවදානමට ලක්විය හැකිය (නිදසුනක් ලෙස, සේවාදායකයාගේ පාලනය යටතේ සමහර විචල්යයන් සහිත සේවාදායක යෙදවීම්
වලදී ක්රියාත්මක කිරීමට සමාන වූ bash
විට එය අර්ථ නිරූපණය කරනු ඇත ).ssh
ForcedCommand
git
දැන්, විශ්වාසදායක නොවන දත්ත සැකසීම සඳහා ස්ක්රිප්ට් එකක් කෙලින්ම කැඳවනු නොලැබේ, නමුත් එය වෙනත් විධානයක් මගින් කැඳවනු ලැබේ. නැතහොත් ඔබගේ වැරදි කේතය පිටපත් වලට පිටපත් කළ හැකිය (ඔබ විසින් වසර 3 ක් පහළට හෝ ඔබේ සගයකුට). ඔබේ කේතයේ පිටපත් අවසන් වන්නේ කොතැනින්දැයි ඔබ කිසි විටෙකත් නොදන්නා බැවින් එය විශේෂයෙන් විවේචනාත්මක වන එක් ප්රශ්නෝත්තර වෙබ් අඩවි වල පිළිතුරු ඇත.
ව්යාපාරයට බැස; එය කෙතරම් නරකද?
විචල්ය (හෝ විධාන ආදේශනය) නම් නොකොට තැබීම ෂෙල් කේතය හා සම්බන්ධ ආරක්ෂක දුර්වලතා වල අංක එකේ ප්රභවය වේ. අර්ධ වශයෙන් එම දෝෂ බොහෝ විට අනාරක්ෂිතභාවයට පරිවර්තනය වන අතර, නොකියවූ විචල්යයන් දැකීම සාමාන්ය දෙයක් වන බැවිනි.
ඇත්ත වශයෙන්ම, ෂෙල් කේතයේ ඇති දුර්වලතා සොයන විට, කළ යුතු පළමු දෙය නම් නොකල විචල්යයන් සොයා බැලීමයි. හඳුනා ගැනීම පහසුය, බොහෝ විට හොඳ අපේක්ෂකයෙකු, සාමාන්යයෙන් ප්රහාරකයා විසින් පාලනය කරන ලද දත්ත වෙත ආපසු යාම පහසුය.
නොකියවූ විචල්යයක් අවදානමට ලක්විය හැකි ආකාර ගණනක් ඇත. මම මෙහි පොදු ප්රවණතා කිහිපයක් දෙන්නම්.
තොරතුරු අනාවරණය කිරීම
බෙදීම් කොටස නිසා බොහෝ අය නම් නොකල විචල්යයන් හා සම්බන්ධ දෝෂ වලට ගොදුරු වනු ඇත (නිදසුනක් ලෙස, වර්තමානයේ ලිපිගොනු වල නම් වල අවකාශයන් තිබීම සාමාන්ය දෙයක් වන අතර අවකාශය IFS හි පෙරනිමි අගයේ පවතී). බොහෝ අය ගෝලීය කොටස නොසලකා හරිනු ඇත
. මෙම glob කොටසක් අවම වශයෙන් ලෙස දරුණු ලෙස ය
භේදය කොටසක්.
අනාරක්ෂිත බාහිර ආදානය මත ග්ලෝබ් කිරීම යනු ඕනෑම නාමාවලියක අන්තර්ගතය කියවීමට ප්රහාරකයාට හැකි වේ.
තුළ:
echo You entered: $unsanitised_external_input
$unsanitised_external_input
අඩංගු නම් /*
, එයින් අදහස් කරන්නේ ප්රහාරකයාට අන්තර්ගතය දැකිය හැකි බවයි /
. ලොකු දෙයක් නැහැ. /home/*
යන්ත්රයේ පරිශීලක නාම ලැයිස්තුවක් /tmp/*
, /home/*/.forward
වෙනත් භයානක භාවිතයන් පිළිබඳ ඉඟි /etc/rc*/*
සඳහා, සක්රීය සේවාවන් සඳහා එය ලබා දෙන නමුත් එය වඩාත් සිත්ගන්නා සුළු වේ ... ඒවා තනි තනිව නම් කිරීම අවශ්ය නොවේ. වටිනාකමකින් /*
/*/* /*/*/*...
මුළු ගොනු පද්ධතියම ලැයිස්තු ගත වේ.
සේවා දුර්වලතා ප්රතික්ෂේප කිරීම.
පෙර නඩුව ටිකක් දුරින් ගෙන අපට DoS එකක් තිබේ.
ඇත්ත වශයෙන්ම, ලැයිස්තුගත සන්දර්භය තුළ සනීපාරක්ෂක නොවන ආදානය සහිත නම් නොකල ඕනෑම විචල්යයක් අවම වශයෙන් DoS අවදානමක් ඇත.
විශේෂ expert ෂෙල් ස්ක්රිප්ටර්වරු පවා මෙවැනි දේ උපුටා දැක්වීමට අමතක කරති:
#! /bin/sh -
: ${QUERYSTRING=$1}
:
no-op විධානයයි. වැරදි විය හැකි දේ කුමක්ද?
බව අනුයුක්ත කිරීමට අදහස් කරනවා $1
කිරීමට $QUERYSTRING
නම් $QUERYSTRING
ශූන්යය විය. විධාන රේඛාවෙන් CGI ස්ක්රිප්ට් එකක් කැඳවිය හැකි ඉක්මන්ම ක්රමයකි.
එය $QUERYSTRING
තවමත් පුළුල් වී ඇති අතර එය උපුටා දක්වා නොමැති නිසා, භේදය + ග්ලෝබ් ක්රියාකරු ආයාචනා කරනු ලැබේ.
දැන්, පුළුල් කිරීම සඳහා විශේෂයෙන් මිල අධික වන ග්ලෝබ් කිහිපයක් තිබේ. මෙම /*/*/*/*
පහළ මට්ටම් 4 බහලුම ලැයිස්තුගත අදහස් ලෙස එක් නරක තරම් වේ. තැටිය සහ CPU ක්රියාකාරකම් වලට අමතරව, එයින් අදහස් වන්නේ දස දහස් ගණනක් ගොනු මාර්ග ගබඩා කිරීමයි (අවම සේවාදායක VM එකක 40k, මෙහි 10k ඩිරෙක්ටරි).
දැන් /*/*/*/*/../../../../*/*/*/*
අදහස් කරන්නේ 40k x 10k වන
/*/*/*/*/../../../../*/*/*/*/../../../../*/*/*/*
අතර බලවත්ම යන්ත්රය පවා දණහිසට ගෙන ඒමට එය ප්රමාණවත් වේ.
එය ඔබම අත්හදා බලන්න (ඔබේ යන්ත්රය බිඳ වැටීමට හෝ එල්ලීමට සූදානම්ව සිටියද):
a='/*/*/*/*/../../../../*/*/*/*/../../../../*/*/*/*' sh -c ': ${a=foo}'
ඇත්ත වශයෙන්ම, කේතය නම්:
echo $QUERYSTRING > /some/file
එවිට ඔබට තැටිය පිරවිය හැකිය.
Shell cgi හෝ bash cgi හෝ ksh cgi හි ගූගල් සෙවුමක් කරන්න , එවිට ඔබට ෂෙල් වෙඩි වලින් CGI ලිවිය යුතු ආකාරය පෙන්වන පිටු කිහිපයක් හමුවනු ඇත. පරාමිතීන් සැකසෙන ඒවායින් අඩක් අවදානමට ලක්වන ආකාරය සැලකිල්ලට ගන්න.
පවා ඩේවිඩ් Korn ම එක්
(මෙම කුකිය හැසිරවීමේ දී පෙනුම) ඇති ඉඩකඩ වැඩි ය.
අත්තනෝමතික කේත ක්රියාත්මක කිරීමේ දුර්වලතා දක්වා
අත්තනෝමතික කේත ක්රියාත්මක කිරීම නරකම ආකාරයේ අවදානමකි, මන්ද ප්රහාරකයාට ඕනෑම විධානයක් ක්රියාත්මක කළ හැකි නම් , ඔහු කළ හැකි දේට සීමාවක් නොමැත.
සාමාන්යයෙන් ඒවාට බෙදී යන කොටස එයයි . එය බෙදීමෙන් ප්රති results ල ලැබෙන්නේ එක් අයෙකු පමණක් බලාපොරොත්තු වූ විට විධාන වෙත යැවීම සඳහා තර්ක කිහිපයක් ය. ඒවායින් පළමුවැන්න අපේක්ෂිත සන්දර්භය තුළ භාවිතා කරනු ඇති අතර අනෙක් ඒවා වෙනස් සන්දර්භයක පවතිනු ඇත. උදාහරණයක් සමඟ වඩා හොඳ:
awk -v foo=$external_input '$2 == foo'
මෙන්න, අභිප්රාය වූයේ $external_input
ෂෙල් විචල්යයේ අන්තර්ගතය
foo
awk
විචල්යයට පැවරීමයි.
දැන්:
$ external_input='x BEGIN{system("uname")}'
$ awk -v foo=$external_input '$2 == foo'
Linux
බෙදීමේ ප්රති result ලයක් ලෙස දෙවන වචනය $external_input
පවරා නැති foo
නමුත් awk
කේතයක් ලෙස සලකනු ලැබේ (මෙහි අත්තනෝමතික විධානයක් ක්රියාත්මක කරයි :) uname
.
බව (අනෙකුත් විධානයන් ක්රියාත්මක කළ හැකි විධාන සඳහා විශේෂයෙන්ම ප්රශ්නයක් awk
, env
, sed
, (GNU එකක්) perl
, find
...) යනු GNU ප්රභේද්යයන් විශේෂයෙන් සමග (තර්ක පසු විකල්ප පිලිගන්නවා). සමහර විට, ඔබ වැනි වෙනත් අය ක්රියාත්මක කිරීමට හැකි විය සැකකරු විධාන නො ksh
, bash
හෝ zsh
ගේ [
හෝ printf
...
for file in *; do
[ -f $file ] || continue
something-that-would-be-dangerous-if-$file-were-a-directory
done
අප නමින් නාමාවලියක් නිර්මාණය කරන්නේ නම් x -o yes
, පරීක්ෂණය ධනාත්මක බවට පත්වේ, මන්ද එය අප ඇගයීමට ලක් කරන සම්පූර්ණයෙන්ම වෙනස් කොන්දේසි සහිත ප්රකාශනයකි.
නරකම දෙය නම්, x -a a[0$(uname>&2)] -gt 1
අවම වශයෙන් සියලු ksh ක්රියාත්මක කිරීම් සහිතව ( sh
බොහෝ වාණිජ ඒකක සහ සමහර BSD ඇතුළත්) ගොනුවක් නිර්මාණය කරන්නේ නම් , එය ක්රියාත්මක uname
වන්නේ එම කවචයන් [
විධානයේ සංඛ්යාත්මක සංසන්දනාත්මක ක්රියාකරුවන් මත ගණිතමය ඇගයීමක් සිදු කරන බැවිනි .
$ touch x 'x -a a[0$(uname>&2)] -gt 1'
$ ksh -c 'for f in *; do [ -f $f ]; done'
Linux
සමග එකම bash
වැනි ගොනු සඳහා x -a -v a[0$(uname>&2)]
.
ඇත්ත වශයෙන්ම, ඔවුන්ට අත්තනෝමතික ලෙස ක්රියාත්මක කිරීමට නොහැකි නම්, ප්රහාරකයා අඩු හානියක් සඳහා විසඳුම් ලබා දිය හැකිය (එය අත්තනෝමතික ලෙස ක්රියාත්මක කිරීමට උපකාරී වේ). ලිපිගොනු ලිවීමට හෝ අවසර වෙනස් කිරීමට, හිමිකාරිත්වය හෝ ප්රධාන හෝ අතුරු ආබාධ ඇති ඕනෑම විධානයක් සූරාකෑමට ලක්විය හැකිය.
සෑම ආකාරයකම ලිපිගොනු නාම වලින් කළ හැකිය.
$ touch -- '-R ..'
$ for file in *; do [ -f "$file" ] && chmod +w $file; done
ඔබ ..
ලිවිය හැකි (GNU සමඟ පුනරාවර්තන ලෙස
chmod
) සෑදීම අවසන් කරයි .
වැනි ප්රසිද්ධියේ ලිවිය හැකි ප්රදේශවල ලිපිගොනු ස්වයංක්රීයව සැකසීමේ පිටපත් /tmp
ඉතා ප්රවේශමෙන් ලිවිය යුතුය.
මොකද කරන්නේ [ $# -gt 1 ]
එය මා කෝපයට පත් කරන දෙයක්. සමහර පුද්ගලයින්ට උපුටා දැක්වීම් මඟ හැරිය හැකිදැයි තීරණය කිරීම සඳහා විශේෂිත ප්රසාරණයක් ගැටළු සහගත විය හැකිදැයි කල්පනා කිරීමේ සියලු කරදර පහව යයි.
එය කියන්නාක් මෙනි. හේයි, එය $#
භේදය + ග්ලෝබ් ක්රියාකරුට යටත් විය නොහැකි බව පෙනේ , අපි ෂෙල් එකෙන් බෙදීමට + ග්ලෝබ් කරන්නැයි ඉල්ලා සිටිමු . නැතහොත් හේයි, දෝෂය ඇතිවීමට ඉඩක් නොමැති නිසා වැරදි කේතයක් ලියමු .
දැන් එය කොතරම් අපහසුද? හරි, $#
(හෝ $!
, $?
හෝ ඕනෑම අංක ගණිත ආදේශකයක්) අඩංගු විය හැක්කේ ඉලක්කම් (හෝ -
සමහරක් සඳහා) නිසා ගෝලීය කොටස ඉවරයි . සඳහා භේදය නමුත් යමක් කිරීමට කොටසක්, අපට අවශ්ය සියලු සඳහා $IFS
ඉලක්කම් (හෝ අඩංගු -
).
සමහර ෂෙල් වෙඩි සමඟ, $IFS
පරිසරයෙන් උරුම විය හැකි නමුත් පරිසරය ආරක්ෂිත නොවේ නම්, එය කෙසේ හෝ අවසන් වේ.
දැන් ඔබ මෙවැනි ශ්රිතයක් ලියන්නේ නම්:
my_function() {
[ $# -eq 2 ] || return
...
}
එයින් අදහස් කරන්නේ ඔබේ ශ්රිතයේ හැසිරීම එය හැඳින්වෙන සන්දර්භය මත රඳා පවතින බවයි. නැතහොත් වෙනත් වචන වලින් කිවහොත්, $IFS
එය සඳහා යෙදවුම් වලින් එකක් බවට පත්වේ. නිශ්චිතවම කිවහොත්, ඔබ ඔබේ කාර්යය සඳහා API ප්රලේඛනය ලියන විට, එය මෙවැනි දෙයක් විය යුතුය:
# my_function
# inputs:
# $1: source directory
# $2: destination directory
# $IFS: used to split $#, expected not to contain digits...
ඔබේ ශ්රිතයට කේත ඇමතීමෙන් $IFS
ඉලක්කම් අඩංගු නොවන බවට වග බලා ගත යුතුය. ඒ සියල්ලම ද්වි-උපුටා දැක්වීමේ අකුරු 2 ටයිප් කිරීමට ඔබට හැඟී නැති නිසාය.
දැන්, එම [ $# -eq 2 ]
දෝෂය අවදානමට ලක්වීමට නම්, ඔබට කෙසේ හෝ ප්රහාරකයාගේ$IFS
පාලනය යටතට පත්වීමේ වටිනාකම අවශ්ය වේ. පෙනෙන ආකාරයට, ප්රහාරකයා වෙනත් දෝෂයක් ගසාකෑමට සමත් වුවහොත් එය සාමාන්යයෙන් සිදු නොවේ .
එය නොඇසූ දෙයක් නොවේ. පොදු කරුණක් වන්නේ ගණිත ප්රකාශනයේ දත්ත භාවිතා කිරීමට පෙර දත්ත සනීපාරක්ෂාව කිරීමට මිනිසුන්ට අමතක වීමයි. සමහර ෂෙල් වෙඩි තුළ අත්තනෝමතික කේත ක්රියාත්මක කිරීමට එයට ඉඩ දිය හැකි බව අපි දැනටමත් දැක ඇත්තෙමු, නමුත් ඒ සියල්ලෙහිම, ප්රහාරකයාට ඕනෑම විචල්යයකට පූර්ණ සංඛ්යාවක් ලබා දීමට ඉඩ දෙයි
.
උදාහරණයක් වශයෙන්:
n=$(($1 + 1))
if [ $# -gt 2 ]; then
echo >&2 "Too many arguments"
exit 1
fi
හා සමග $1
වටිනාකම (IFS=-1234567890)
, එම අංක ගණිතමය ඇගයීම සැකසුම් IFS පැත්තේ බලපාන අතර ඊළඟ [
විධානය සඳහා වන චෙක්පත, ඉන් අදහස් වන්නේ අසමත් බොහෝ args අතුරු මාර්ගයක් ඇත.
භේදය + ග්ලෝබ් ක්රියාකරු ආයාචනා නොකළ විට කුමක් කළ යුතුද?
විචල්යයන් සහ වෙනත් පුළුල් කිරීම් වටා මිල ගණන් අවශ්ය වන තවත් අවස්ථාවක් තිබේ: එය රටාවක් ලෙස භාවිතා කරන විට.
[[ $a = $b ]] # a `ksh` construct also supported by `bash`
case $a in ($b) ...; esac
එක $a
හා සමානද යන්න පරීක්ෂා නොකරන්න $b
(හැර zsh
) නමුත් $a
රටාවට ගැලපෙන්නේ නම් $b
. ඔබ උපුටා ගැනීමට අවශ්ය $b
ඔබ නූල් ලෙස සංසන්දනය කිරීමට අවශ්ය නම් (එකම දෙයක් ගැන "${a#$b}"
හෝ "${a%$b}"
හෝ "${a##*$b*}"
එහිදී $b
එය රටාවක් ලෙස ගත යුතු නෑ නම් උපුටා ගත යුතුය).
කුමක්ද යන්න ප්රකාශ වේ [[ $a = $b ]]
අවස්ථාවන්හීදී සැබෑ ආපසු හැක $a
වෙනස් වේ $b
(උදාහරණයක් ලෙස විට $a
ය anything
සහ $b
ය *
) හෝ ඔවුන් සමාන (දෙකම, උදාහරණයක් විට බොරු ආපසු හැක $a
සහ $b
ය [a]
).
එය ආරක්ෂිත අවදානමක් ඇති කළ හැකිද? ඔව්, ඕනෑම දෝෂයක් වගේ. මෙන්න, ප්රහාරකයාට ඔබගේ ස්ක්රිප්ටයේ තාර්කික කේත ප්රවාහය වෙනස් කිරීමට සහ / හෝ ඔබේ ස්ක්රිප්ට් කරන උපකල්පන බිඳ දැමිය හැකිය. උදාහරණයක් ලෙස, වැනි කේතයක් සමඟ:
if [[ $1 = $2 ]]; then
echo >&2 '$1 and $2 cannot be the same or damage will incur'
exit 1
fi
පහර දෙන්නාට චෙක්පත මඟ හැරිය හැක '[a]' '[a]'
.
දැන්, එම රටා ගැලපීම හෝ භේදය + ග්ලෝබ් ක්රියාකරු අදාළ නොවේ නම්, විචල්යයක් නොකියවා තැබීමේ අන්තරාය කුමක්ද?
මා ලියන බව පිළිගත යුතුය:
a=$b
case $a in...
එහිදී, උපුටා දැක්වීම හානියක් නොවන නමුත් දැඩි ලෙස අවශ්ය නොවේ.
කෙසේ වෙතත්, එම අවස්ථා වලදී උපුටා දැක්වීම් මඟ හැරීමේ එක් අතුරු effect ලයක් නම් (නිදසුනක් ලෙස ප්රශ්නෝත්තර පිළිතුරු වල) එය ආරම්භකයින්ට වැරදි පණිවිඩයක් යැවිය හැකි ය: විචල්යයන් උපුටා දැක්වීම නොකිරීම හරි ය .
නිදසුනක් ලෙස, ඔවුන් සිතීමට පටන් ගත හැකිය a=$b
, හරි නම් , එය එසේම export a=$b
වනු ඇත ( එය බොහෝ ෂෙල් වෙඩි වල නොමැති බැවින් එය export
විධානයට තර්ක කරන බැවින් ලැයිස්තු සන්දර්භය තුළ) හෝ env a=$b
.
කුමක් ගැනද zsh
?
zsh
එම නිර්මාණයේ බොහෝ අමුතුකම් නිවැරදි කර ඇත. දී zsh
(අවම වශයෙන් විට sh / ksh මාත කර නැති), ඔබට අවශ්ය නම් පැලෙන හෝ globbing , හෝ රටාව ගැලපෙන , ඔබ සතුව ඒ සඳහා ඉල්ලුම් කිරීමට ඇති: $=var
භේදය, සහ $~var
glob හෝ ලෙස සැලකිය යුතුයි විචල්ය අන්තර්ගතය සඳහා රටාවක්.
කෙසේ වෙතත්, බෙදීම (නමුත් ග්ලෝබ් කිරීම නොවේ) තවමත් ව්යංගයෙන් සිදු කරනුයේ නම් නොකල විධාන ආදේශනය මත ය (මෙන් echo $(cmd)
).
එසේම, විචල්යය උපුටා නොකිරීමේ සමහර විට අනවශ්ය අතුරු ආබාධයක් වන්නේ හිස් ඉවත් කිරීමයි. zsh
ග්ලෝබ් කිරීම සම්පූර්ණයෙන්ම (සමග set -f
) අක්රීය කිරීමෙන් සහ (සමඟ IFS=''
) බෙදීමෙන් ඔබට වෙනත් ෂෙල් වෙඩි වලින් ලබා ගත හැකි දේට මෙම හැසිරීම සමාන වේ . තවමත්, තුළ:
cmd $var
බෙදීම් + ග්ලෝබ් එකක් නොතිබෙනු ඇත , නමුත් $var
හිස් නම් , එක් හිස් තර්කයක් ලබා ගැනීම වෙනුවට, cmd
කිසිදු තර්කයක් නොලැබේ.
එය දෝෂ ඇති කළ හැකිය (පැහැදිලිව පෙනෙන පරිදි [ -n $var ]
). එය ස්ක්රිප්ට් එකක අපේක්ෂාවන් සහ උපකල්පන බිඳ දැමිය හැකි අතර අනාරක්ෂිතභාවයට හේතු විය හැක, නමුත් මට දැන් එතරම් දුරට ලබා ගත නොහැකි උදාහරණයක් ඉදිරිපත් කළ නොහැක).
ඔබට භේදය + ග්ලෝබ් ක්රියාකරු අවශ්ය වූ විට කුමක් කළ යුතුද?
ඔව්, එය සාමාන්යයෙන් ඔබේ විචල්යය නොසලකා හැරීමට අවශ්ය විටය. නමුත් ඔබ එය භාවිතා කිරීමට පෙර ඔබේ භේදය හා ග්ලෝබ් ක්රියාකරුවන් නිවැරදිව සුසර කරන බවට වග බලා ගත යුතුය. ඔබට අවශ්ය වන්නේ බෙදීම් කොටස මිස ග්ලෝබ් කොටස නොවේ (බොහෝ විට එය එසේ වේ), එවිට ඔබට ග්ලෝබින් ( set -o noglob
/ set -f
) අක්රීය කර නිවැරදි කළ $IFS
යුතුය. එසේ නොමැතිනම් ඔබ ද අවදානම් ඇති කරයි (ඉහත සඳහන් කළ ඩේවිඩ් කෝර්න්ගේ සීජීඅයි උදාහරණය වැනි).
නිගමනය
කෙටියෙන් කිවහොත්, විචල්යයක් (හෝ විධාන ආදේශනය හෝ අංක ගණිත විස්තාරණය) ෂෙල් වෙඩි වල සටහන් නොකිරීම සැබවින්ම භයානක විය හැකිය, විශේෂයෙන් වැරදි සන්දර්භයන් තුළ සිදු කරන විට, එම වැරදි සන්දර්භයන් මොනවාදැයි දැන ගැනීම ඉතා අපහසුය.
එය නරක පුරුද්දක් ලෙස සැලකීමට එක් හේතුවකි .
මෙතෙක් කියවීමට ස්තූතියි. එය ඔබේ හිසට ඉහළින් ගියහොත්, කරදර නොවන්න. සෑම කෙනෙකුම තම කේතය ලිවීමේදී එය ලිවීමේ සියලු ඇඟවුම් තේරුම් ගනී යැයි අපේක්ෂා කළ නොහැකිය. අපට හොඳ පුහුණු නිර්දේශයන් ඇත්තේ එබැවිනි
, එබැවින් අවශ්යතාවය තේරුම් නොගෙන ඒවා අනුගමනය කළ හැකිය.
(එය තවම පැහැදිලි නැතිනම් කරුණාකර ආරක්ෂක සංවේදී කේත ෂෙල් වෙඩි වලින් ලිවීමෙන් වළකින්න).
හා මෙම වෙබ් අඩවිය ඔබේ පිළිතුරු ඔබේ විචල්ය උපුටා කරුණාකරලා!
ksh93
සහ pdksh
සහ ව්යුත්පන්නයන්හි, ග්ලෝබින් අක්රීය කර නොමැති නම් වරහන් ප්රසාරණය ද සිදු කරනු ලැබේ ( ksh93
ksh93u + දක්වා වූ අනුවාද වලදී, braceexpand
විකල්පය අක්රිය වූ විට පවා ).