मैं बैश उदाहरण पढ़ रहा हूँ, if
लेकिन कुछ उदाहरण एकल वर्ग कोष्ठक के साथ लिखे गए हैं:
if [ -f $param ]
then
#...
fi
डबल वर्ग कोष्ठक के साथ अन्य:
if [[ $? -ne 0 ]]
then
start looking for errors in yourlog
fi
अंतर क्या है?
मैं बैश उदाहरण पढ़ रहा हूँ, if
लेकिन कुछ उदाहरण एकल वर्ग कोष्ठक के साथ लिखे गए हैं:
if [ -f $param ]
then
#...
fi
डबल वर्ग कोष्ठक के साथ अन्य:
if [[ $? -ne 0 ]]
then
start looking for errors in yourlog
fi
अंतर क्या है?
जवाबों:
सिंगल []
पॉज़िक्स शेल कंप्लेंट कंडीशन टेस्ट हैं।
डबल [[]]
मानक के लिए एक विस्तार []
हैं और बैश और अन्य गोले (जैसे zsh, ksh) द्वारा समर्थित हैं। वे अतिरिक्त संचालन (साथ ही मानक पॉज़िक्स संचालन) का समर्थन करते हैं। उदाहरण के लिए: के ||
बजाय -o
और regex के साथ मिलान =~
। सशर्त निर्माणों पर बाश मैनुअल अनुभाग में मतभेदों की एक फुलर सूची पाई जा सकती है ।
का प्रयोग करें []
जब भी आप अपनी स्क्रिप्ट के गोले भर में पोर्टेबल होना चाहता हूँ। [[]]
यदि आप सशर्त अभिव्यक्ति का समर्थन नहीं करना चाहते हैं []
और पोर्टेबल होने की आवश्यकता नहीं है, तो उपयोग करें ।
[[ ]]
(उदाहरण के साथ #!/bin/bash
या #!/usr/bin/env bash
), तो आपको पोर्टेबल विकल्प का उपयोग करना चाहिए। इस तरह के मान / बिन / श का समर्थन करने वाले लिपियों का हाल के डेबियन और उबंटू रिलीज जैसे ओएस पर टूट जाएगा जहां ऐसा नहीं है।
व्यवहार में अंतर
बैश में परीक्षण 4.3.11:
POSIX बनाम बैश एक्सटेंशन:
[
POSIX है[[
एक बैश एक्सटेंशन है जिसे यहाँ पर प्रलेखित किया गया है: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructsमैजिक बनाम रेगुलर कमांड
[
एक अजीब नाम के साथ सिर्फ एक नियमित आदेश है।
]
सिर्फ एक तर्क है [
जो आगे के तर्कों का उपयोग करने से रोकता है।
Ubuntu 16.04 वास्तव में इसके लिए एक निष्पादन योग्य है जो /usr/bin/[
कोर्यूटिल्स द्वारा प्रदान किया गया है, लेकिन बैश बिल्ट-इन संस्करण पूर्वता लेता है।
बैश कमांड को पार्स करने के तरीके में कोई बदलाव नहीं किया गया है।
विशेष रूप से, <
पुनर्निर्देशन होता है, &&
और ||
कई आदेशों को समाप्त ( )
करता है \
, जब तक कि बच नहीं जाता , तब तक उप-जनरेट करता है , और शब्द विस्तार सामान्य रूप से होता है।
[[ X ]]
एक एकल निर्माण है जिसे X
जादुई रूप से पार्स किया जाता है। <
, और &&
, विशेष रूप से व्यवहार किया जाता है, और शब्द विभाजन नियम अलग हैं।||
()
आगे =
और भी अंतर हैं जैसे और =~
।
Bashese में: [
एक अंतर्निहित कमांड है, और [[
एक कीवर्ड है: /ubuntu/445749/whats-the-difference-between-shell-builtin-and-shell-bword
<
[[ a < b ]]
: कोशिकीय तुलना[ a \< b ]
: ऊपर की तरह। \
आवश्यक है या किसी अन्य आदेश के लिए पुनर्निर्देशन पसंद है। बैश विस्तार।expr a \< b > /dev/null
: POSIX समतुल्य, देखें: बैश में कम या बराबर के लिए स्ट्रिंग्स का परीक्षण कैसे करें?&&
तथा ||
[[ 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 ]
: समतुल्य, लेकिन ()
पोसिक्स द्वारा पदावनत किया जाता है{ [ 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 हालांकि समूहीकरण (यहाँ के साथ {...;}
आदेश समूह के बजाय (...)
जो एक अनावश्यक subshell चल पाएंगे) नहीं के रूप में आवश्यक है ||
और &&
खोल ऑपरेटरों (के रूप में करने का विरोध किया ||
और &&
[[...]]
ऑपरेटर या -o
/ -a
[
ऑपरेटरों) बराबर पूर्वता है। तो [ a = a ] || [ a = b ] && [ a = b ]
समकक्ष होगा।
[]
को मेरी प्राथमिकता के रूप में पढ़ा जाना चाहिए : []
यदि आप पोर्टेबिलिटी नहीं खोना चाहते हैं तो उपयोग करें । जैसा कि यहां कहा गया है : यदि पोसिक्स या बॉर्नशेल के लिए पोर्टेबिलिटी / अनुरूपता एक चिंता का विषय है, तो पुराने सिंटैक्स का उपयोग किया जाना चाहिए। यदि दूसरी ओर स्क्रिप्ट के लिए BASH, Zsh या KornShell की आवश्यकता होती है, तो नया सिंटैक्स आमतौर पर अधिक लचीला होता है, लेकिन जरूरी नहीं कि पीछे की ओर संगत हो। मैं इसके बजाय जाऊँगा [[ ab =~ ab? ]]
अगर मुझे पिछड़े अनुकूलता के बारे में कोई चिंता नहीं हैprintf 'ab' | grep -Eq 'ab?'
हालत परीक्षण (अर्थात [...]) के लिए एकल ब्रैकेट के अंदर, कुछ ऑपरेटर जैसे सिंगल =
को सभी शेल द्वारा समर्थित किया जाता है, जबकि ऑपरेटर ==
का उपयोग पुराने शेल में से कुछ द्वारा समर्थित नहीं है।
हालत परीक्षण (यानी [[...]]) के लिए डबल कोष्ठक के अंदर, वहाँ का उपयोग कर के बीच कोई अंतर नहीं है =
या ==
पुराने या नए गोले में।
संपादित करें: मुझे यह भी ध्यान देना चाहिए कि: बैश में, यदि संभव हो तो हमेशा डबल ब्रैकेट [[...]] का उपयोग करें, क्योंकि यह एकल ब्रैकेट की तुलना में अधिक सुरक्षित है। मैं उदाहरण के साथ क्यों उदाहरण देता हूँ:
if [ $var == "hello" ]; then
यदि $ var अशक्त / रिक्त होता है, तो यह वही है जो स्क्रिप्ट देखता है:
if [ == "hello" ]; then
जो आपकी स्क्रिप्ट को तोड़ देगा। इसका समाधान या तो डबल ब्रैकेट का उपयोग करना है, या हमेशा अपने चर के आसपास उद्धरण रखना याद रखें ( "$var"
)। डबल ब्रैकेट बेहतर रक्षात्मक कोडिंग अभ्यास है।
[[
[
कमांड के समान (लेकिन उससे अधिक शक्तिशाली) एक बैश कीवर्ड है ।
देख
http://mywiki.wooledge.org/BashFAQ/031 और http://mywiki.wooledge.org/BashGuide/TestsAndConditionals
जब तक आप POSIX sh के लिए नहीं लिख रहे, हम अनुशंसा करते हैं [[
।
आप प्रकाश रेगेक्स मिलान के लिए डबल वर्ग कोष्ठक का उपयोग कर सकते हैं, जैसे:
if [[ $1 =~ "foo.*bar" ]] ; then
(जब तक आप bash का संस्करण प्रयोग कर रहे हैं, तब तक आप इस वाक्य रचना का समर्थन करते हैं)
बैश मैनुअल कहते हैं:
जब [[, '<' और '>' संचालकों के साथ वर्तमान लोकेल का उपयोग करते हुए शब्दशः क्रमबद्ध किया जाता है। परीक्षण आदेश ASCII आदेश का उपयोग करता है।
(परीक्षण आदेश [] के समान है)