डबल या सिंगल ब्रैकेट, कोष्ठक, घुंघराले ब्रेसिज़ का उपयोग कैसे करें


657

मैं बैश में ब्रैकेट्स, कोष्ठक, घुंघराले ब्रेसिज़ के उपयोग से भ्रमित हूं, साथ ही उनके दोहरे या एकल रूपों के बीच का अंतर भी। क्या कोई स्पष्ट व्याख्या है?

जवाबों:


605

बैश में, testऔर [शेल बिलिन हैं।

डबल ब्रैकेट है, जो एक खोल कीवर्ड है, अतिरिक्त कार्यक्षमता सक्षम बनाता है। उदाहरण के लिए, आप उपयोग कर सकते हैं &&और ||इसके बजाय -aऔर -oएक नियमित अभिव्यक्ति मिलान ऑपरेटर है =~

इसके अलावा, एक साधारण परीक्षण में, डबल वर्ग ब्रैकेट एकल लोगों की तुलना में काफी तेज मूल्यांकन करते हैं।

$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done

real    0m24.548s
user    0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done

real    0m33.478s
user    0m33.478s
sys 0m0.000s

ब्रेसिज़, एक चर नाम को परिसीमन करने के अलावा पैरामीटर विस्तार के लिए उपयोग किया जाता है ताकि आप निम्न कार्य कर सकें:

  • एक चर की सामग्री को काटें

    $ var="abcde"; echo ${var%d*}
    abc
  • के समान प्रतिस्थापन करें sed

    $ var="abcde"; echo ${var/de/12}
    abc12
  • एक डिफ़ॉल्ट मान का उपयोग करें

    $ default="hello"; unset var; echo ${var:-$default}
    hello
  • और कई और अधिक

इसके अलावा, ब्रेस एक्सपेंशन स्ट्रिंग्स की सूची बनाते हैं जो आम तौर पर छोरों पर आधारित होते हैं:

$ echo f{oo,ee,a}d
food feed fad

$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")

$ for num in {000..2}; do echo "$num"; done
000
001
002

$ echo {00..8..2}
00 02 04 06 08

$ echo {D..T..4}
D H L P T

ध्यान दें कि प्रमुख शून्य और वेतन वृद्धि सुविधाएँ बैश 4 से पहले उपलब्ध नहीं थीं।

ब्रेस एक्सपैंशन के बारे में याद दिलाने के लिए gboffi का शुक्रिया।

डबल कोष्ठक का उपयोग अंकगणितीय संचालन के लिए किया जाता है :

((a++))

((meaning = 42))

for ((i=0; i<10; i++))

echo $((a + b + (14 * c)))

और वे आपको पूर्णांक और सरणी चर पर डॉलर के संकेतों को छोड़ने में सक्षम करते हैं और पठनीयता के लिए ऑपरेटरों के आसपास रिक्त स्थान शामिल करते हैं।

एकल ब्रैकेट का उपयोग सरणी सूचकांकों के लिए भी किया जाता है :

array[4]="hello"

element=${array[index]}

दाहिने हाथ की ओर (ज्यादातर / सभी?) सरणी संदर्भों के लिए घुंघराले ब्रेस आवश्यक हैं।

ephemient की टिप्पणी ने मुझे याद दिलाया कि कोष्ठक का उपयोग उप-श्रेणियों के लिए भी किया जाता है। और उनका उपयोग arrays बनाने के लिए किया जाता है।

array=(1 2 3)
echo ${array[1]}
2

8
चेतावनी: यह फ़ंक्शन एक फोर्क बम है, इसे न चलाएं। देखें: en.wikipedia.org/wiki/Fork_bomb
अगली सूचना तक रोक दिया गया।

3
यह केवल एक कांटा बम है यदि आप इसे एक अतिरिक्त के साथ लेते हैं :
इफिशिएंट

7
पूर्णता के लिए भी, मैं अभी एक पुरानी स्क्रिप्ट में आया था $[expression]:; यह नए, पसंदीदा वाक्यविन्यास के लिए पुराना, पदावनत अंकगणितीय अभिव्यक्ति वाक्यविन्यास है:$((expression))
माइकल

2
@DennisWilliamson में घुंघराले ब्रेसिज़ का एक और उपयोग bashअनुक्रम बना रहा है, जैसा कि नीचे दिए गए परिधीय रूप से उल्लेख किया गया है ( stackoverflow.com/a/8552128/2749397 ) जैसा कि मैं इस सुविधा के बारे में थोड़ा टिप्पणी करना चाहूंगा (जैसा कि आपने इसका उल्लेख नहीं किया है; ;-)) एक वाहन के रूप में सबसे अधिक वोट दिए गए उत्तर का उपयोग करने की स्वतंत्रता लेते हुए ... अनुक्रम के दो उदाहरण शाब्दिक: echo {01..12}-> 01 02 03 04 05 06 07 08 09 10 11 12(प्रारंभिक शून्य पर ध्यान दें); echo {C..Q}-> C D E F G H I J K L M N O P Q। इसका मुख्य उपयोग छोरों में है, जैसे for cnt in {01..12} ; do ... ${cnt} ... ; done
gboffi

1
@ बागोफी: शून्य पैडिंग सुविधा बाश 4 में उपलब्ध हो गई। इसके अलावा, बाश 4 में, आप एक क्रम में वृद्धि को निर्दिष्ट कर सकते हैं: echo {01..12..2}-> "01 03 05 07 09 09 11"। दृश्यों के बारे में अनुस्मारक के लिए धन्यवाद। मैं इसे अपने जवाब में जोड़ दूंगा।
अगली सूचना तक रोक दिया गया।

335
  1. एक एकल ब्रैकेट ( [) आमतौर पर नाम के एक कार्यक्रम को बुलाता है [; man testया man [अधिक जानकारी के लिए। उदाहरण:

    $ VARIABLE=abcdef
    $ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
    yes
  2. डबल ब्रैकेट ( [[) एक ही ब्रैकेट के रूप में एक ही चीज़ (मूल रूप से) करता है, लेकिन एक बैश बिलिन है।

    $ VARIABLE=abcdef
    $ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
    no
  3. कोष्ठक ()बनाने के लिए कोष्ठक ( ) का उपयोग किया जाता है। उदाहरण के लिए:

    $ pwd
    /home/user 
    $ (cd /tmp; pwd)
    /tmp
    $ pwd
    /home/user

    जैसा कि आप देख सकते हैं, उपधारा ने आपको वर्तमान शेल के वातावरण को प्रभावित किए बिना संचालन करने की अनुमति दी।

  4. (ए) ब्रेसिज़ ( {}) का उपयोग चर को स्पष्ट रूप से पहचानने के लिए किया जाता है। उदाहरण:

    $ VARIABLE=abcdef
    $ echo Variable: $VARIABLE
    Variable: abcdef
    $ echo Variable: $VARIABLE123456
    Variable:
    $ echo Variable: ${VARIABLE}123456
    Variable: abcdef123456

    (बी) ब्रेस का उपयोग वर्तमान शेल संदर्भ में आदेशों के अनुक्रम को निष्पादित करने के लिए भी किया जाता है , जैसे

    $ { date; top -b -n1 | head ; } >logfile 
    # 'date' and 'top' output are concatenated, 
    # could be useful sometimes to hunt for a top loader )
    
    $ { date; make 2>&1; date; } | tee logfile
    # now we can calculate the duration of a build from the logfile

( )हालांकि, ( बैश संदर्भ देखें ) के साथ एक सूक्ष्म वाक्यविन्यास अंतर है ; अनिवार्य रूप से, ;ब्रेसिज़ के भीतर अंतिम आदेश के बाद एक अर्धविराम एक होना चाहिए, और ब्रेसिज़ {, रिक्त स्थान से घिरा } होना चाहिए।


26
ठीक है, [वास्तव में बैश में एक बिलिन है, लेकिन यह बिलियन के /bin/[विपरीत कार्य करने वाला है [[[[अलग-अलग विशेषताएं हैं, जैसे अधिक तार्किक संचालन और अलग-अलग उद्धरण भूमिकाएं। इसके अतिरिक्त: एकल कोष्ठक का उपयोग सरणियों, प्रक्रिया प्रतिस्थापन और विस्तारित ग्लोब के लिए भी किया जाता है; डबल कोष्ठक अंकगणित के लिए उपयोग किया जाता है; घुंघराले ब्रेसिज़ {}का उपयोग कमांड ग्रुपिंग या पैरामीटर विस्तार या ब्रेस विस्तार या अनुक्रम विस्तार के प्रकार के मल्टीट्यूड के लिए किया जाता है। मुझे यकीन है कि मैंने कुछ अन्य उपयोगों को भी याद कर लिया है ...
२२:४०

4
अभिव्यक्ति में डबल-बराबरी if [ $VARIABLE == abcdef ] एक बशीवाद है - हालांकि यह काम करता है - शायद बचा जाना चाहिए; या तो स्पष्ट रूप से bash ( if [[ ...==...]]) का उपयोग करें या यह स्पष्ट करें कि आप अधिक पारंपरिक सशर्त ( if [ "$VARIABLE" = "abcdef" ]) का उपयोग कर रहे हैं । तर्क है, लिपियों को यथासंभव सरल और पोर्टेबल शुरू करना चाहिए, जब तक कि उन्हें वास्तव में बैश (एक कारण या किसी अन्य) के लिए विशिष्ट विशेषताओं की आवश्यकता न हो। लेकिन किसी भी मामले में, इरादा स्पष्ट होना चाहिए; "=" और "==" और "[[" और "[" अलग तरीके से काम करते हैं और उनका उपयोग सुसंगत होना चाहिए।
माइकल

3
इस टिप्पणी के लिए @michael_n: +1। एक साइड नोट पर, मुझे स्क्रिप्टिंग बहुत पसंद है, लेकिन मुझे यह बहुत अजीब लगता है कि पोर्टेबल तरीका [ "$var" = ".."]इसके बजाय परीक्षण करना है ==, जबकि सी में यह परीक्षण के बजाय असाइन करेगा (और कीड़े का एक सामान्य कारण है) ... क्यों नहीं किया 'के बजाय का testउपयोग करें ? कोई जानता है? ===
ओलिवियर दुलैक

यहाँ भी एक मजेदार बात यह है कि (कम से कम कुबंटु पर) कमांड /usr/bin/[एक सिम्क्लिन नहीं है /usr/bin/test, और अधिक: इन कार्यक्रमों में कुछ अलग आकार भी हैं!
हाय-एंजेल

इसके अलावा: एक एकल समापन कोष्ठक एक केस लाइन को समाप्त करने के लिए वाक्यविन्यास )का हिस्सा है case। इसमें शुरुआती कोष्ठक नहीं है। यह मुझे पहली बार देखा जब मैंने इसे फेंक दिया।
अगस्टिन अमेनाबर

302

कोष्ठक

if [ CONDITION ]    Test construct  
if [[ CONDITION ]]  Extended test construct  
Array[1]=element1   Array initialization  
[a-z]               Range of characters within a Regular Expression
$[ expression ]     A non-standard & obsolete version of $(( expression )) [1]

[१] http://wiki.bash-hackers.org/scripting/obirect

घुंघराले ब्रेसिज़

${variable}                             Parameter substitution  
${!variable}                            Indirect variable reference  
{ command1; command2; . . . commandN; } Block of code  
{string1,string2,string3,...}           Brace expansion  
{a..z}                                  Extended brace expansion  
{}                                      Text replacement, after find and xargs

कोष्टक

( command1; command2 )             Command group executed within a subshell  
Array=(element1 element2 element3) Array initialization  
result=$(COMMAND)                  Command substitution, new style  
>(COMMAND)                         Process substitution  
<(COMMAND)                         Process substitution 

डबल कोष्ठक

(( var = 78 ))            Integer arithmetic   
var=$(( 20 + 5 ))         Integer arithmetic, with variable assignment   
(( var++ ))               C-style variable increment   
(( var-- ))               C-style variable decrement   
(( var0 = var1<98?9:21 )) C-style ternary operation

@ योला, क्या आप बता सकते हैं कि वास्तव में $ (varname) क्या है? Apple Xcode परियोजनाओं में, मैं स्क्रिप्ट इनपुट / आउटपुट के रूप में फ़ाइल पथ निर्दिष्ट कर सकता हूं। अगर मैं $ SRC_ROOT / myFile.txt या $ {SRC_ROOT} /myFile.txt (SRC_ROOT var को निर्यात प्रणाली द्वारा निर्यात किया जाता है) निर्दिष्ट करता हूं - तो काम नहीं करता। केवल $ (SRC_ROOT) /myFile.txt काम करता है। क्या कारण हो सकता है? स्पष्ट रूप से var नाम एक कमांड नहीं है?
मॉटी श्नोर

1
@MotiShneor, आपके मामले $(varname)में वाक्यविन्यास को कोसने के लिए असंबंधित है। यह मेकफाइल सिंटैक्स का हिस्सा है ।
साशा

ऐसा नहीं है - Xcode मेकफाइल का उपयोग कर निर्माण नहीं कर रहा है और इसके चर पर्यावरण चर हैं। मालिकाना Xcode बिल्ड-सिस्टम प्रक्रियाएं इन पूर्वनिर्धारित पर्यावरण चर के मूल्यों को पढ़ती हैं। कस्टम-बिल्ड-स्टेप्स केवल सामान्य शेल-स्क्रिप्ट (बैश या अन्य) हैं और एक ही संस्करण तक पहुंच रखते हैं।
मॉटी श्नोर

@MottiShneor, ठीक है, आइए परिष्कृत करें: सबसे शायद यह xcconfig सिंटैक्स का हिस्सा है । वैसे भी, $(varname)आपके मामले में वाक्य रचना को कोसने से कोई संबंध नहीं है।
साशा

आप परीक्षण निर्माण और विस्तारित परीक्षण निर्माण के बीच अंतर क्या है का उल्लेख नहीं करते हैं।
निकोस

23

मैं सिर्फ TLDP से इन्हें जोड़ना चाहता था :

~:$ echo $SHELL
/bin/bash

~:$ echo ${#SHELL}
9

~:$ ARRAY=(one two three)

~:$ echo ${#ARRAY}
3

~:$ echo ${TEST:-test}
test

~:$ echo $TEST


~:$ export TEST=a_string

~:$ echo ${TEST:-test}
a_string

~:$ echo ${TEST2:-$TEST}
a_string

~:$ echo $TEST2


~:$ echo ${TEST2:=$TEST}
a_string

~:$ echo $TEST2
a_string

~:$ export STRING="thisisaverylongname"

~:$ echo ${STRING:4}
isaverylongname

~:$ echo ${STRING:6:5}
avery

~:$ echo ${ARRAY[*]}
one two one three one four

~:$ echo ${ARRAY[*]#one}
two three four

~:$ echo ${ARRAY[*]#t}
one wo one hree one four

~:$ echo ${ARRAY[*]#t*}
one wo one hree one four

~:$ echo ${ARRAY[*]##t*}
one one one four

~:$ echo $STRING
thisisaverylongname

~:$ echo ${STRING%name}
thisisaverylong

~:$ echo ${STRING/name/string}
thisisaverylongstring

18
मन जो echo ${#ARRAY}तीन को प्रदर्शित करता है, ARRAYउसमें तीन तत्वों के पहले तत्व के कारण होता है, इसलिए नहीं कि इसमें तीन तत्व होते हैं! तत्वों के उपयोग की संख्या मुद्रित करने के लिए echo ${#ARRAY[@]}
ट्रू

@ वील ${TEST:-test}बराबर होता है $TESTयदि चर TESTमौजूद है, अन्यथा यह केवल स्ट्रिंग "परीक्षण" लौटाता है। एक और संस्करण है जो और भी अधिक करता है: ${TEST:=test}--- जो $TESTTEST के मौजूद होने के बराबर भी होता है, लेकिन जब भी ऐसा नहीं होता है, तो यह वैरिएबल बनाता है TESTऔर "टेस्ट" मान देता है और पूरे एक्सप्रेशन का मान भी बन जाता है।
संभावित

18

बाशफा में परीक्षण , [ और [के बीच के अंतर को महान विवरण में समझाया गया है ।

एक लंबी कहानी को छोटा करने के लिए: परीक्षण कमांड के पुराने, पोर्टेबल सिंटैक्स को लागू करता है। लगभग सभी गोले में (सबसे पुराना बॉर्न गोले अपवाद हैं), [परीक्षण का पर्याय है (लेकिन अंतिम तर्क की आवश्यकता है)। यद्यपि सभी आधुनिक गोले में [के कार्यान्वयन में अंतर्निहित हैं, आमतौर पर अभी भी उस नाम का एक बाहरी निष्पादन योग्य है, जैसे / बिन / [।

[[इसका एक नया उन्नत संस्करण है, जो एक कीवर्ड है, एक कार्यक्रम नहीं है। यह उपयोग में आसानी पर लाभकारी प्रभाव है, जैसा कि नीचे दिखाया गया है। [[कोर्नशेल और BASH (जैसे 2.03) द्वारा समझा जाता है, लेकिन पुराने POSIX या बॉर्नशेल द्वारा नहीं।

और निष्कर्ष:

नया परीक्षण आदेश [[कब प्रयोग किया जाना चाहिए, और पुराना कब होना चाहिए]? यदि BourneShell के लिए पोर्टेबिलिटी एक चिंता का विषय है, तो पुराने सिंटैक्स का उपयोग किया जाना चाहिए। यदि दूसरी ओर स्क्रिप्ट को BASH या KornShell की आवश्यकता होती है, तो नया सिंटैक्स बहुत अधिक लचीला होता है।


18

फ़ंक्शन परिभाषा में कोष्ठक

कोष्ठक ()का उपयोग फ़ंक्शन परिभाषा में किया जा रहा है:

function_name () { command1 ; command2 ; }

यही कारण है कि आपको कमांड पैरामीटर में भी कोष्ठक से बचना होगा:

$ echo (
bash: syntax error near unexpected token `newline'

$ echo \(
(

$ echo () { command echo The command echo was redefined. ; }
$ echo anything
The command echo was redefined.

ओह मैंने csh पर कोशिश की। मेरी गलती। जब मैं बैश पर कोशिश करता हूं, तो यह काम करता है। मुझे बाश की कमांड 'कमांड' नहीं पता थी।
किम

मैं कमांड गूंज () को कैसे पुनर्परिभाषित कर सकता हूं? (बैश को फिर से खोलने के बिना)
चान किम

2
@ChanKim: unset -f echo। देखते हैं help unset
17

0
Truncate the contents of a variable

$ var="abcde"; echo ${var%d*}
abc

Make substitutions similar to sed

$ var="abcde"; echo ${var/de/12}
abc12

Use a default value

$ default="hello"; unset var; echo ${var:-$default}
hello

जब आप एक प्रश्न का उत्तर देते हैं, तो केवल "कोड" के लिए लक्ष्य न रखें, बल्कि एक स्पष्टीकरण को जोड़ने का भी प्रयास करें ...
माइक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.