मैं बस सोच रहा था कि वास्तव में क्या अंतर है
[[ $STRING != foo ]]
तथा
[ $STRING != foo ]
इसके अलावा, बाद वाला पॉज़िक्स-कम्प्लायंट है, जो श में पाया जाता है और पूर्व एक विस्तार है जो बैश में पाया जाता है।
मैं बस सोच रहा था कि वास्तव में क्या अंतर है
[[ $STRING != foo ]]
तथा
[ $STRING != foo ]
इसके अलावा, बाद वाला पॉज़िक्स-कम्प्लायंट है, जो श में पाया जाता है और पूर्व एक विस्तार है जो बैश में पाया जाता है।
जवाबों:
कई अंतर हैं। मेरी राय में, कुछ सबसे महत्वपूर्ण हैं:
[
बैश और कई अन्य आधुनिक गोले में एक बिलिन है। बिलिन एक समापन की अतिरिक्त आवश्यकता के [
समान है । बिल्डरों और कार्यक्षमता का अनुकरण और उनकी सीमाओं के साथ ताकि स्क्रिप्ट्स पीछे की ओर संगत हों। मूल निष्पादनयोग्य अभी भी ज्यादातर POSIX अनुपालन और पीछे की संगतता के लिए मौजूद हैं। बाश में कमांड चलाना इंगित करता है कि डिफ़ॉल्ट रूप से एक बिलिन के रूप में व्याख्या की गई है। (नोट: केवल पर निष्पादनयोग्य के लिए लग रहा है पथ और के बराबर है )test
]
[
test
/bin/[
/bin/test
type [
[
which [
type -p [
[[
के रूप में संगत नहीं है, यह जरूरी नहीं कि जो कुछ भी /bin/sh
बिंदुओं के साथ काम करेगा । तो [[
अधिक आधुनिक बैश / Zsh / Ksh विकल्प है।[[
शेल में बनाया गया है और विरासत की आवश्यकताएं नहीं हैं, आपको IFS चर पर आधारित शब्द विभाजन के बारे में चिंता करने की आवश्यकता नहीं है, जो रिक्त स्थान के साथ स्ट्रिंग का मूल्यांकन करने वाले चर पर गड़बड़ करने के लिए है। इसलिए, आपको वास्तव में चर को दोहरे उद्धरण चिह्नों में रखने की आवश्यकता नहीं है।अधिकांश भाग के लिए, बाकी सिर्फ कुछ अच्छे सिंटैक्स हैं। अधिक अंतर देखने के लिए, मैं इस लिंक को अक्सर पूछे जाने वाले प्रश्न का उत्तर देने की सलाह देता हूं: परीक्षण, [और [] के बीच अंतर क्या है? । वास्तव में, यदि आप बैश स्क्रिप्टिंग के बारे में गंभीर हैं, तो मैं FAQ, नुकसान और गाइड सहित संपूर्ण विकि पढ़ने की सलाह देता हूं । गाइड अनुभाग से परीक्षण अनुभाग इन अंतरों को भी बताता है, और क्यों लेखक (लेखक) को लगता है कि एक बेहतर विकल्प है यदि आपको पोर्टेबल होने के बारे में चिंता करने की आवश्यकता नहीं है। मुख्य कारण हैं:[[
< >
इनपुट पुनर्निर्देशन के रूप में मूल्यांकन न करने के लिए बैकस्लैश की तुलना में कम और अधिक से अधिक भागना नहीं है, जो कि ओवरराइटिंग फ़ाइलों द्वारा कुछ सामान को गड़बड़ कर सकता है। यह फिर से [[
एक बेसिन होने के लिए वापस चला जाता है । यदि [(परीक्षण) एक बाहरी कार्यक्रम है, तो शेल को मूल्यांकन करने के तरीके में एक अपवाद बनाना होगा <
और >
केवल अगर /bin/test
इसे बुलाया जा रहा है, जो वास्तव में समझ में नहीं आएगा।संक्षेप में:
[बैश बिलिन है
[[]] बैश कीवर्ड हैं
कीवर्ड: कीवर्ड बिल्ट बिल्डिंग की तरह होते हैं, लेकिन मुख्य अंतर यह है कि विशेष पार्सिंग नियम उन पर लागू होते हैं। उदाहरण के लिए, [एक बैश बिलियन है, जबकि [[एक बैश कीवर्ड है। वे दोनों सामान के परीक्षण के लिए उपयोग किए जाते हैं, लेकिन चूंकि [[बिलियन के बजाय एक कीवर्ड है, यह कुछ विशेष पार्सिंग नियमों से लाभ देता है जो इसे बहुत आसान बनाते हैं:
$ [ a < b ]
-bash: b: No such file or directory
$ [[ a < b ]]
पहला उदाहरण एक त्रुटि देता है क्योंकि bash फ़ाइल b को कमांड [a] पर पुनर्निर्देशित करने की कोशिश करता है। दूसरा उदाहरण वास्तव में वही करता है जो आप उससे उम्मीद करते हैं। चरित्र <अब फ़ाइल पुनर्निर्देशन ऑपरेटर का अपना विशेष अर्थ नहीं है।
स्रोत: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments
[
POSIX शेल कमांड है; इसे बनाने की आवश्यकता नहीं है। ]
यह केवल एक तर्क है जो कि कमांड के लिए दिखता है, ताकि वाक्यविन्यास संतुलित हो। कमांड एक पर्यायवाची है, test
सिवाय इसके कि test
कोई समापन नहीं दिखता है ]
।
व्यवहार में अंतर
बैश 4.3.11 पर कुछ अंतर:
POSIX बनाम बैश एक्सटेंशन:
[
POSIX है[[
एक बैश एक्सटेंशन है जिसे यहाँ पर प्रलेखित किया गया है: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructsमैजिक बनाम रेगुलर कमांड
[
एक अजीब नाम के साथ सिर्फ एक नियमित आदेश है।
]
सिर्फ एक तर्क है [
जो आगे के तर्कों का उपयोग करने से रोकता है।
Ubuntu 16.04 वास्तव में इसके लिए एक निष्पादन योग्य है जो /usr/bin/[
कोरुटिल्स द्वारा प्रदान किया गया है, लेकिन बैश बिल्ट-इन संस्करण पूर्वता लेता है।
बैश कमांड को पार्स करने के तरीके में कोई बदलाव नहीं किया गया है।
विशेष रूप से, <
पुनर्निर्देशन होता है, &&
और ||
कई आदेशों को समाप्त ( )
करता है \
, जब तक कि बच नहीं जाता , तब तक उप-जनरेट करता है , और शब्द विस्तार सामान्य रूप से होता है।
[[ X ]]
एक एकल निर्माण है जिसे X
जादुई रूप से पार्स किया जाता है। <
, और &&
, विशेष रूप से व्यवहार किया जाता है, और शब्द विभाजन नियम अलग हैं।||
()
आगे =
और भी अंतर हैं जैसे और =~
।
Bashese में: [
एक अंतर्निहित कमांड है, और [[
एक कीवर्ड है: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-bword
<
[[ a < b ]]
: कोशिकीय तुलना[ a \< b ]
: ऊपर की तरह। \
आवश्यक है या किसी अन्य आदेश के लिए पुनर्निर्देशन पसंद है। बैश विस्तार।expr a \< b > /dev/null
: POSIX समतुल्य, देखें: https://stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989&&
तथा ||
[[ a = a && b = b ]]
: सत्य, तार्किक और[ a = a && b = b ]
: सिंटैक्स त्रुटि, &&
और कमांड विभाजक के रूप में पार्स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 ]
: समतुल्य, लेकिन ()
पोसिक्स द्वारा पदावनत किया जाता है{ [ 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? ]]
: सच है, क्योंकि यह पैटर्न मिलान ( * ? [
जादू है) करता है। मौजूदा निर्देशिका में फ़ाइलों के लिए ग्लोब का विस्तार नहीं करता है।[ ab = a? ]
: a?
ग्लोब फैलता है। तो वर्तमान निर्देशिका में फ़ाइलों के आधार पर सही या गलत हो सकता है।[ ab = a\? ]
: असत्य, ग्लोब विस्तार नहीं=
और ==
दोनों में ही कर रहे हैं [
और [[
, लेकिन ==
एक बैश विस्तार है।case ab in (a?) echo match; esac
: POSIX बराबर[[ ab =~ 'ab?' ]]
: झूठी 4 , के साथ जादू खो देता है''
[[ ab? =~ 'ab?' ]]
: सच=~
[[ ab =~ ab? ]]
: सच है, POSIX ने नियमित अभिव्यक्ति मैच बढ़ाया , ?
ग्लोब का विस्तार नहीं हुआ[ a =~ a ]
: वक्य रचना त्रुटि। कोई बैश के बराबर नहीं।printf 'ab\n' | grep -Eq 'ab?'
: POSIX समतुल्य (केवल एकल पंक्ति डेटा)awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?'
: POSIX बराबर।सिफ़ारिश : हमेशा उपयोग []
।
[[ ]]
मेरे द्वारा देखे गए प्रत्येक निर्माण के लिए POSIX समकक्ष हैं ।
यदि आप का उपयोग करें [[ ]]
:
[
एक अजीब नाम के साथ सिर्फ एक नियमित आदेश है, कोई विशेष शब्दार्थ शामिल नहीं है।¹ [[...]]
कोर्न शेल में समतुल्य निर्माण से प्रेरित
² लेकिन के कुछ मूल्यों के लिए विफल रहता है 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
। ()
कि आदेश पर की जरूरत नहीं किया जा सकता है मुझे यकीन है कि नहीं कर रहा हूँ: मैं इसकी वजह से जोड़ा |
, कैसे बैश चीजों को पार्स करता है पर निर्भर करता है। अगर वहाँ नहीं था तो |
मुझे यकीन है कि आप बस लिख सकते हैं if cmd arg arg; then
।
()
लगती है: stackoverflow.com/questions/8965509/…
एकल ब्रैकेट यानी []
एक सशर्त अभिव्यक्ति को संलग्न करने के लिए POSIX खोल अनुपालन है।
डबल ब्रैकेट्स यानी [[]]
मानक POSIX संस्करण का वर्धित (या एक्सटेंशन) संस्करण है, यह बैश और अन्य गोले (zsh, ksh) द्वारा समर्थित है।
बैश में, अंकीय तुलना उपयोग हम के लिए 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