මම කල්පනා කළා හරියටම හරියටම වෙනස මොකක්ද කියලා
[[ $STRING != foo ]]
හා
[ $STRING != foo ]
ඊට අමතරව, දෙවැන්න පොසික්ස්-අනුකූල වන අතර, එය sh වලින් සොයාගත හැකි අතර, පළමුවැන්න බාෂ් වලින් සොයාගත් දිගුවකි.
මම කල්පනා කළා හරියටම හරියටම වෙනස මොකක්ද කියලා
[[ $STRING != foo ]]
හා
[ $STRING != foo ]
ඊට අමතරව, දෙවැන්න පොසික්ස්-අනුකූල වන අතර, එය sh වලින් සොයාගත හැකි අතර, පළමුවැන්න බාෂ් වලින් සොයාගත් දිගුවකි.
Answers:
වෙනස්කම් කිහිපයක් තිබේ. මගේ මතය අනුව, වඩාත්ම වැදගත් කරුණු කිහිපයක් නම්:
[
යනු බාෂ් සහ තවත් බොහෝ නූතන ෂෙල් වෙඩි වලින් නිමවා ඇත. බිල්ඩින් වසා දැමීමේ අතිරේක අවශ්යතාවයට [
සමානය . ස්ක්රිප්ට් පසුපසට අනුකූල වන පරිදි බිල්ඩින් සහ ක්රියාකාරීත්වය සහ ඒවායේ සීමාවන් අනුකරණය කරයි . මුල් ක්රියාත්මක කළ හැකි දෑ තවමත් බොහෝ දුරට පවතින්නේ පොසික්ස් අනුකූලතාවය සහ පසුගාමී අනුකූලතාව සඳහා ය. Bash හි විධානය ක්රියාත්මක කිරීමෙන් ඇඟවෙන්නේ එය පෙරනිමියෙන් බිල්ඩින් ලෙස අර්ථකථනය කර ඇති බවයි. (සටහන: PATH හි ක්රියාත්මක කළ හැකි දේ පමණක් සොයන අතර එය සමාන වේ )test
]
[
test
/bin/[
/bin/test
type [
[
which [
type -p [
[[
එතරම් අනුකූල නොවේ, එය අනිවාර්යයෙන්ම ඕනෑම කරුණක් සමඟ ක්රියා නොකරනු /bin/sh
ඇත. ඒ නිසා [[
, වඩාත් නූතන බෑෂ් / Zsh / Ksh විකල්පය වේ.[[
ෂෙල් බවට ඉදිකර ඇත සහ උරුමය අවශ්යතා නැහැ, ඔබ මත පදනම් වචනය පැලෙන ගැන කරදර විය යුතු නැත IFS හිස් අවකාශයක් වැලක් කිරීමට ඇගයීමට බව විචල්ය මත අවුල් කිරීමට විචල්ය. එමනිසා, ඔබට විචල්යය ද්විත්ව උපුටා දැක්වීම් කිරීමට අවශ්ය නැත.බොහෝ දුරට, ඉතිරිය වඩා හොඳ වාක්ය ඛණ්ඩයකි. තවත් වෙනස්කම් දැකීමට, මම නිතර අසන පැන පිළිතුරකට මෙම සබැඳිය නිර්දේශ කරමි: පරීක්ෂණය, [සහ [[? . ඇත්ත වශයෙන්ම, ඔබ බාෂ් ස්ක්රිප්ටින් ගැන බැරෑරුම් නම් , නිතර අසනු ලබන ප්රශ්න, අන්තරායන් සහ මාර්ගෝපදේශය ඇතුළුව සමස්ත විකියම කියවීමට මම නිර්දේශ කරමි . මාර්ගෝපදේශ අංශයේ පරීක්ෂණ අංශය මෙම වෙනස්කම් ද පැහැදිලි කරයි, සහ අතේ ගෙන යා හැකි වීම ගැන කරදර වීමට අවශ්ය නොවන්නේ නම් කතුවරයා (ය) වඩා හොඳ තේරීමක් යැයි සිතන්නේ ඇයි . ප්රධාන හේතු:[[
< >
ආදාන යළි-යොමුවීමක් ලෙස ඇගයීමට ලක් නොකිරීම සඳහා ඔබට බැක්ස්ලෑෂ් වලට වඩා අඩු හා විශාල වශයෙන් පැන යා යුතු නැත , එමඟින් ලිපිගොනු නැවත ලිවීමෙන් සමහර දේවල් අවුල් කළ හැකිය. මෙය යළිත් [[
ගොඩනඟන්නෙකු බවට පත්වේ. [(ටෙස්ට්) බාහිර වැඩසටහන නම් ෂෙල් එය ඇගයීමට ලක් මාර්ගය ගැන ව්යතිරේකයක් කිරීමට සිදුවන <
හා >
නම් පමණක් /bin/test
තේරුමක් නැහැ අතර, ඉල්ලා කොට ඇත.කෙටියෙන්:
[යනු බාෂ් බිල්ටින් ය
[[]] යනු මූලික වචන වේ
මූල පද: මූල පද සෑදී ඇත්තේ බිල්ඩින් වැනි ය, නමුත් ප්රධාන වෙනස වන්නේ විශේෂ විග්රහ කිරීමේ නීති ඒවාට අදාළ වීමයි. උදාහරණයක් ලෙස, [යනු bash buildin වන අතර [[යනු bash keyword වේ. ඒවා දෙකම දේවල් පරීක්ෂා කිරීම සඳහා භාවිතා කරයි, නමුත් [[බිල්ඩින් එකකට වඩා යතුරු පදයක් බැවින්, එය විශේෂ විග්රහ කිරීමේ නීති කිහිපයකින් ප්රතිලාභ ලබන අතර එය වඩාත් පහසු කරයි:
$ [ a < b ]
-bash: b: No such file or directory
$ [[ a < b ]]
පළමු උදාහරණය දෝෂයක් ලබා දෙන්නේ බාෂ් විසින් ගොනුව b විධානය වෙත හරවා යැවීමට උත්සාහ කරන බැවිනි [a]. දෙවන උදාහරණය ඇත්ත වශයෙන්ම ඔබ අපේක්ෂා කරන දේ කරයි. <අක්ෂරයට තවදුරටත් ගොනු හරවා යැවීමේ ක්රියාකරුගේ විශේෂ අරුතක් නොමැත.
මුලාශ්රය: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments
[
POSIX shell විධානයකි; එය ගොඩනඟා ගත යුතු නොවේ. ]
එම විධානය සොයන තර්කයක් පමණක් වන අතර එමඟින් වාක්ය ඛණ්ඩය සමතුලිත වේ. මෙම විධානය සඳහා යොදාගන්නා පද පර්යාය test
බව හැර test
ඇති අවසන් සොයන්නේ නැත ]
.
චර්යා වෙනස්කම්
Bash 4.3.11 හි සමහර වෙනස්කම්:
POSIX එදිරිව Bash දිගුව:
[
POSIX වේ[[
යනු බාෂ් දිගුවකි: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructsනිත්ය විධානය එදිරිව මැජික්
[
යනු අමුතු නමක් සහිත සාමාන්ය විධානයකි.
]
එය [
තවත් තර්කයක් භාවිතා කිරීම වළක්වයි.
උබුන්ටු 16.04 හි ඇත්ත වශයෙන්ම එය ක්රියාත්මක කළ හැකි වන්නේ /usr/bin/[
කොරුටිල්ස් විසිනි, නමුත් බාෂ් බිල්ට් අනුවාදයට ප්රමුඛස්ථානයක් ගනී.
Bash විධානය විග්රහ කරන ආකාරයට කිසිවක් වෙනස් නොවේ.
විශේෂයෙන්, <
යළි හරවා යැවීම, &&
සහ ||
බහු විධානයන් සංයුක්ත කිරීම, එයින් ( )
ගැලවී නොගියහොත් උප-ෂෙල් ජනනය කරයි \
, සහ වචන ප්රසාරණය සුපුරුදු පරිදි සිදු වේ.
[[ X ]]
යනු X
ඉන්ද්රජාලිකව විග්රහ කළ හැකි තනි ඉදිකිරීමකි . <
, &&
, ||
හා ()
විශේෂයෙන් ප්රතිකාර කර ඇති අතර, වචනය පැලෙන නීති වෙනස් වේ.
=
සහ වැනි තවත් වෙනස්කම් =~
තිබේ.
බෂීස් හි: [
ගොඩනංවන ලද විධානයක් වන අතර [[
එය ප්රධාන පදයකි : /ubuntu/445749/whats-the-difference-between-shell-builtin-and-shell-keyword
<
[[ a < b ]]
: ශබ්දකෝෂ සංසන්දනය[ a \< b ]
: ඉහත ආකාරයටම. \
අවශ්ය හෝ වෙනත් විධානයකට යළි හරවා යැවීම අවශ්ය වේ. බෑෂ් දිගුව.expr a \< b > /dev/null
: POSIX equal², බලන්න: /programming/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989&&
හා ||
[[ a = a && b = b ]]
: සත්ය, තාර්කික සහ[ a = a && b = b ]
: සින්ටැක්ස් දෝෂය, &&
AND විධාන බෙදුම්කරුවෙකු ලෙස විග්රහ කර ඇතcmd1 && cmd2
[ a = a -a b = b ]
: සමාන, නමුත් POSIX³ විසින් ප්රතික්ෂේප කරන ලදි[ a = a ] && [ b = b ]
: POSIX සහ විශ්වාසනීය සමාන(
[[ (a = a || a = b) && a = b ]]
: අසත්ය[ ( a = a ) ]
: සින්ටැක්ස් දෝෂය, උප ()
අක්ෂරයක් ලෙස අර්ථ දැක්වේ[ \( a = a -o a = b \) -a a = b ]
: සමාන, නමුත් ()
POSIX විසින් ප්රතික්ෂේප කරනු ලැබේ{ [ a = a ] || [ a = b ]; } && [ a = b ]
POSIX සමාන 5පුළුල් කිරීම මත වචන බෙදීම සහ ගොනු නාම උත්පාදනය (භේදය + ග්ලෝබ්)
x='a b'; [[ $x = 'a b' ]]
: ඇත්ත, උපුටා දැක්වීම් අවශ්ය නොවේx='a b'; [ $x = 'a b' ]
: සින්ටැක්ස් දෝෂය, දක්වා පුළුල් වේ [ a b = 'a b' ]
x='*'; [ $x = 'a b' ]
: වත්මන් නාමාවලියෙහි එක් ගොනුවකට වඩා තිබේ නම් සින්ටැක්ස් දෝෂයකි.x='a b'; [ "$x" = 'a b' ]
: POSIX සමාන=
[[ ab = a? ]]
: true, මන්ද එය රටා ගැලපීම ( * ? [
මැජික්) නිසා. වත්මන් නාමාවලියෙහි ඇති ගොනු වෙත ග්ලෝබ් පුළුල් නොවේ.[ ab = a? ]
: a?
ග්ලෝබ් පුළුල් වේ. එබැවින් වත්මන් නාමාවලියෙහි ඇති ගොනු මත පදනම්ව සත්ය හෝ අසත්ය විය හැකිය.[ ab = a\? ]
: අසත්ය, ගෝලීය ව්යාප්තිය නොවේ=
සහ ==
දෙකෙහිම එක [
හා සමාන වේ [[
, නමුත් ==
එය Bash දිගුවකි.case ab in (a?) echo match; esac
: POSIX සමාන[[ ab =~ 'ab?' ]]
: ව්යාජ 4 , සමඟ මැජික් නැති වේ''
[[ ab? =~ 'ab?' ]]
: සැබෑ=~
[[ ab =~ ab? ]]
: true, POSIX දිගු කරන ලද නිත්ය ප්රකාශන ගැලපීම, ?
ගෝලීය පුළුල් නොවේ[ a =~ a ]
: සින්ටැක්ස් දෝෂයකි. බාෂ් සමාන නොවේ.printf 'ab\n' | grep -Eq 'ab?'
: POSIX සමාන (තනි පේළි දත්ත පමණි)awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?'
: POSIX සමාන.නිර්දේශය : සැමවිටම භාවිතා කරන්න []
.
[[ ]]
මා දුටු සෑම ඉදිකිරීමක් සඳහාම POSIX සමානකම් ඇත.
ඔබ ඔබ භාවිතා කරන්නේ [[ ]]
නම්:
[
යනු අමුතු නමක් සහිත සාමාන්ය විධානයක් පමණි, විශේෂ අර්ථකථන කිසිවක් සම්බන්ධ නොවේ.Orn [[...]]
කෝර්න් කවචයේ සමාන ඉදිකිරීම් වලින් ආශ්වාදයක්
² නමුත් සමහර අගයන් a
හෝ b
(වැනි +
හෝ index
) අසමත් වන අතර සංඛ්යාත්මක සංසන්දනය කරන්නේ නම් a
සහ b
දශම සංඛ්යා ලෙස පෙනේ. expr "x$a" '<' "x$b"
දෙකම වටා ක්රියා කරයි.
³ තවද සමහර අගයන් a
හෝ b
කැමති !
හෝ හෝ අසමත් වේ (
.
4 බැෂ් 3.2 සහ ඊට ඉහළින් ඇති අතර බැෂ් 3.1 සඳහා අනුකූලතාවය සක්රිය කර නොමැත (වැනි BASH_COMPAT=3.1
)
5 සහ ෂෙල් ක්රියාකරුවන්ට ( සහ ක්රියාකරුවන්ට හෝ / ක්රියාකරුවන්ට වෙනස්ව ) සමාන ප්රමුඛතාවයක් ඇති බැවින් කණ්ඩායම් කිරීම (මෙහි {...;}
විධාන කණ්ඩායම වෙනුවට (...)
අනවශ්ය උපසිරැසියක් ක්රියාත්මක කිරීම) අවශ්ය නොවේ . එබැවින් සමාන වනු ඇත.||
&&
||
&&
[[...]]
-o
-a
[
[ a = a ] || [ a = b ] && [ a = b ]
printf 'ab' | grep -Eq 'ab?'
ඇතුළත භාවිතා කරන්නේ කෙසේද if [ … ]
?
if ( printf 'ab' | grep -Eq 'a' ); then echo 'a'; fi
. []
විධානයක් වගේ grep
. මෙම ()
මට විශ්වාස නෑ විධානය මත අවශ්ය නොවේ: මම නිසා එය එකතු |
, බෑෂ් දේවල් parses ආකාරය මත රඳා පවතී. නැතිනම් |
මට විශ්වාසයි ඔබට ලිවිය හැකිය if cmd arg arg; then
.
තනි වරහන එනම් []
කොන්දේසි සහිත ප්රකාශනයක් කොටු කිරීමට පොසික්ස් ෂෙල් අනුකූල වේ.
ද්විත්ව කොටු වරහන් එනම් [[]]
සම්මත POSIX අනුවාදය ක වැඩි (හෝ දීර්ඝ) අනුවාදය වන අතර, මෙම bash සහ අනෙකුත් ෂෙල් වෙඩි (zsh, ksh) විසින් ආධාර කරනු ලබයි.
Bash දී, සංඛ්යාත්මක සැසඳීම් සඳහා අප භාවිතා eq
, ne
, lt
හා gt
අපි භාවිතා කළ හැකි සැසඳීම් සඳහා ද්විත්ව කොටු වරහන් සමග, ==
, !=
, <,
හා >
වචනාර්ථයෙන්.
[
යනු පරීක්ෂණ විධානය සඳහා සමාන පදයකි. එය කවචයට සාදා තිබුණත් එය නව ක්රියාවලියක් නිර්මාණය කරයි.[[
එය නව වැඩිදියුණු කළ අනුවාදයකි, එය මූල පදයක් මිස වැඩසටහනක් නොවේ. උදාහරණයක් වශයෙන්:
[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works
if
ප්රකාශයක සන්දර්භය තුළ , mywiki.wooledge.org/BashPitfalls#if_.5Bgrep_foo_myfile.5D