Çift veya tek parantez, parantez, kıvırcık parantez nasıl kullanılır


658

Bash'de parantez, parantez, kıvırcık parantez kullanımı ve bunların çift veya tek formları arasındaki farktan şaşkınım. Açık bir açıklama var mı?

Yanıtlar:


606

Bash testve [kabuk yapıları vardır.

Çift ayraç bir kabuk anahtar kelimedir, ek işlevler sağlar. Örneğin, kullanabileceğiniz &&ve ||yerine -ave -obir düzenli ifade eşleşen operatörü var =~.

Ayrıca, basit bir testte, çift köşeli parantezlerin tekli olanlardan çok daha hızlı olduğu görülmektedir.

$ 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

Parantezler, değişken adını sınırlandırmanın yanı sıra parametre genişletme için kullanılır, böylece aşağıdakileri yapabilirsiniz:

  • Bir değişkenin içeriğini kısalt

    $ var="abcde"; echo ${var%d*}
    abc
  • Şununla benzer ikameler yapın: sed

    $ var="abcde"; echo ${var/de/12}
    abc12
  • Varsayılan bir değer kullan

    $ default="hello"; unset var; echo ${var:-$default}
    hello
  • ve daha fazlası

Ayrıca, küme ayracı genişletmeleri, genellikle döngülerde yinelenen dizelerin listelerini oluşturur:

$ 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

Baştaki sıfır ve artış özelliklerinin Bash 4'ten önce mevcut olmadığını unutmayın.

Brace genişletmelerini hatırlattığı için gboffi'ye teşekkürler.

Aritmetik işlemler için çift parantez kullanılır :

((a++))

((meaning = 42))

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

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

tamsayı ve dizi değişkenlerindeki dolar işaretlerini atlamanıza ve okunabilirlik için işleçlerin etrafına boşluk eklemenize olanak tanır.

Dizi dizinleri için tekli ayraçlar da kullanılır :

array[4]="hello"

element=${array[index]}

Sağ taraftaki (çoğu / tümü?) Dizi başvuruları için süslü ayraç gereklidir.

ephemient'in yorumu, parantezlerin alt kabuklar için de kullanıldığını hatırlattı. Ve diziler oluşturmak için kullanıldığını.

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

8
UYARI: Bu işlev çatal bombasıdır, çalıştırmayın. Bakınız: en.wikipedia.org/wiki/Fork_bomb
sonraki duyuruya kadar duraklatıldı.

3
Sadece bir çatalla patlarsanız, bir çatal bombası :.
ephemient

7
Ayrıca bütünlük için, eski bir senaryoda bununla karşılaştım $[expression]:; Bu, daha yeni, tercih edilen sözdizimi için eski, kullanımdan kaldırılmış aritmetik ifade sözdizimi:$((expression))
michael

2
@DennisWilliamson Kıvırcık parantezlerin bir başka kullanımı, bashaşağıda çevresel olarak belirtildiği gibi diziler oluşturmaktır ( stackoverflow.com/a/8552128/2749397 ) Biraz bu özelliği yorumlamak istediğim gibi (bahsetmediğin gibi ;-) I ' m en çok oyu alan cevabı araç olarak kullanma özgürlüğünü almak ... Sıralı dizilimin iki örneği: echo {01..12}-> 01 02 03 04 05 06 07 08 09 10 11 12(ilk sıfırı not edin); echo {C..Q}-> C D E F G H I J K L M N O P Q. Ana kullanımı döngüler, örneğin, for cnt in {01..12} ; do ... ${cnt} ... ; done
gboffi

1
@gboffi: Sıfır dolgu özelliği Bash 4'te kullanıma sunuldu. Ayrıca Bash 4'te sırasıyla bir artış belirleyebilirsiniz: echo {01..12..2}-> "01 03 05 07 09 11". Dizilerle ilgili hatırlatma için teşekkürler. Cevabıma ekleyeceğim.
sonraki duyuruya kadar duraklatıldı.

336
  1. Tek bir parantez ( [) genellikle adlı bir programı çağırır [; man testveya man [daha fazla bilgi için. Misal:

    $ VARIABLE=abcdef
    $ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi
    yes
  2. Çift köşeli ayraç ( [[) tek bir köşeli ayraçla aynı şeyi yapar (temelde), ancak bir bash yerleşiktir.

    $ VARIABLE=abcdef
    $ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi
    no
  3. Parantezler (() ), bir alt kabuk oluşturmak için kullanılır. Örneğin:

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

    Gördüğünüz gibi alt kabuk, geçerli kabuğun ortamını etkilemeden işlemleri gerçekleştirmenize izin verdi.

  4. (a) Parantezler ( {}) değişkenleri açık bir şekilde tanımlamak için kullanılır. Misal:

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

    (b) Parantezler, geçerli kabuk bağlamında bir komut dizisini yürütmek için de kullanılır;

    $ { 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

Bununla birlikte ( ), ince bir sözdizimsel fark vardır (bkz. Bash referansı ); esasen, bir noktalı virgül ;parantez içinde son komutundan sonra bir zorunluluktur ve parantez {, } gereken boşluklarla çevrili.


26
Aslında, [Bash'te bir yerleşiktir, ancak yerleşikin /bin/[aksine davranması gerekiyordu [[. [[daha mantıklı işlemler ve farklı alıntı rolleri gibi farklı özelliklere sahiptir. Ek olarak: diziler, işlem ikamesi ve uzatılmış globlar için tekli parantezler de kullanılır; aritmetik için çift parantez kullanılır; kıvırcık ayraçlar {}, komut gruplaması veya parametre genişletme veya küme genişletme veya dizi genişletme türlerinin çok sayıdaları için kullanılır. Eminim başka kullanımları da kaçırdım ...
ephemient

4
if [ $VARIABLE == abcdef ]İfadedeki çift ​​eşittir - çalışmasına rağmen - muhtemelen kaçınılması gereken bir bashizmdir; ya bash ( if [[ ...==...]]) yöntemini açıkça kullanın ya da daha geleneksel koşullu ( if [ "$VARIABLE" = "abcdef" ]) yöntemini kullandığınızı açıkça belirtin . Tartışmalı olarak, komut dosyaları, bash'a özgü özelliklere gerçekten ihtiyaç duyana kadar (bir nedenden ötürü) mümkün olduğunca basit ve taşınabilir şekilde başlamalıdır. Ancak her durumda, amaç açık olmalıdır; "=" ve "==" ve "[[" ve ​​"[" farklı çalışır ve kullanımları tutarlı olmalıdır.
michael

3
@michael_n: Bu açıklama için +1. Bir yan notta, komut dosyası yazmayı seviyorum, ancak taşınabilir yolun [ "$var" = ".."]yerine test etmek oldukça garip buluyorum ==, oysa C'de test yerine atayacaktı (ve hataların oldukça yaygın bir nedeni) ... neden yapmadı 't testkullanmak ==yerine =? kimse biliyor mu?
Olivier Dulac

Ayrıca, komik bir şey (en azından Kubuntu'da) komutun /usr/bin/[bir symlink olmadığı /usr/bin/testve daha fazlası: bu programların birkaç farklı boyutu bile var!
Hi-Angel

Ayrıca: tek bir kapanış parantezi ), casebir vaka satırını sonlandırmak için deyim sözdiziminin bir parçasıdır . Açılış parantezi yoktur. Bu beni ilk gördüğümde attı.
Agustín Amenabar

302

Parantez

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]

[1] http://wiki.bash-hackers.org/scripting/obsolete

Kıvırcık Parantez

${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

Parantez

( 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 

Çift Parantez

(( 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

@Yola, $ (varname) 'nin tam olarak ne yaptığını açıklar mısınız? Apple Xcode projelerinde, dosya yollarını komut dosyası giriş / çıkış olarak belirtebilirim. $ SRC_ROOT / myFile.txt veya $ {SRC_ROOT} /myFile.txt belirtirseniz (SRC_ROOT var derleme sistemi tarafından dışa aktarılır) - çalışmaz. yalnızca $ (SRC_ROOT) /myFile.txt dosyası çalışır. Nedeni ne olabilir? açıkça var name bir komut değil mi?
Motti Shneor

1
@MottiShneor, sizin durumunuzda $(varname)bash sözdizimi ile ilgisi yoktur. Makefile sözdiziminin bir parçasıdır .
Sasha

Öyle değil - Xcode makefile's kullanarak yapılamıyor ve değişkenleri ortam değişkenleridir. Tescilli Xcode yapı sistemi süreçleri, bu önceden tanımlanmış ortam değişkenlerinin değerlerini okur. Özel oluşturma adımları yalnızca normal kabuk komut dosyalarıdır (bash veya diğerleri) ve aynı değişkenlere erişebilir.
Motti Shneor

@MottiShneor, tamam, rafine edelim: büyük olasılıkla xcconfig sözdiziminin bir parçasıdır . Her neyse, $(varname)sizin durumunuzda bash sözdizimi ile bir ilişkisi yoktur.
Sasha

Test yapısı ile genişletilmiş test yapısı arasındaki farkın ne olduğunu söylemezsiniz.
Nikos

23

Bunları sadece TLDP'den eklemek istedim :

~:$ 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
Üç karakter içerdiğinden, üç öğeyi içerdiğinden değil, üç karakterin içerdiği için üç tane echo ${#ARRAY}görüntüleyen akıl ARRAY! Öğe sayısını yazdırmak için kullanın echo ${#ARRAY[@]}.
TrueY

@zeal değişkeni varsa ${TEST:-test}eşittir , aksi takdirde "test" dizesini döndürür. Daha da fazlasını yapan başka bir sürüm daha vardır: --- bu da TEST'in var olup olmadığına eşittir , ancak her yokken değişkeni oluşturur ve bir değer "test" atar ve ayrıca tüm ifadenin değeri olur. $TESTTEST${TEST:=test}$TESTTEST
Olasılığı

18

Arasındaki fark testi , [ ve [[ büyük ayrıntılı olarak açıklanmıştır BashFAQ .

Uzun bir hikaye kısa kesmek için: test, komutun eski, taşınabilir sözdizimini uygular. Neredeyse tüm kabuklarda (en eski Bourne kabukları istisnadır), [testin eşanlamlısıdır (ancak son argümanı gerektirir]). Tüm modern mermilerin yerleşik uygulamaları [olmasına rağmen, genellikle bu adın harici bir yürütülebilir dosyası vardır, örneğin / bin / [.

[[bunun yeni bir geliştirilmiş sürümüdür, bir anahtar kelime değildir, bir program değildir. Bunun, aşağıda gösterildiği gibi kullanım kolaylığı üzerinde yararlı etkileri vardır. [[KornShell ve BASH (örneğin 2.03) tarafından anlaşılır, ancak eski POSIX veya BourneShell tarafından anlaşılmaz.

Ve sonuç:

Ne zaman yeni test komutu [[kullanılmalı ve ne zaman eskisi [? BourneShell'e taşınabilirlik önemliyse, eski sözdizimi kullanılmalıdır. Öte yandan komut dosyası BASH veya KornShell gerektiriyorsa, yeni sözdizimi çok daha esnektir.


18

İşlev tanımında parantezler

Parantezler ()işlev tanımında kullanılmaktadır:

function_name () { command1 ; command2 ; }

Komut parametrelerinde bile parantezlerden kaçmanızın nedeni budur:

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

$ echo \(
(

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

Oh ben csh denedim. Benim hatam. Ben bash denediğimde, işe yarıyor. Bash'in 'komutu' komutunu bilmiyordum.
Chan Kim

echo () komutunun yeniden tanımlanmasını nasıl iptal edebilirim? (bash'ı yeniden açmadan)
Chan Kim

2
@ChanKim: unset -f echo. Bkz help unset.
pabouk

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

Bir soruyu cevapladığınızda, sadece "kod" u hedeflemeyin, aynı zamanda bir açıklama eklemeye çalışın ...
Mikev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.