Bash'ta () vs. {} ne zaman kullanılır?


74

Ben Bash kabuk komut dosyası okuyorum ve ben arasındaki farkı bilmek gerekir (...)ve {...}. Bir senaryo yazarken ikisi arasında nasıl bir seçim yapılır?



3
Sadece komut grubu bağlamında mı demek istediniz?
heemayl

Yanıtlar:


87

Komut listesinin yan etkilerinin geçerli kabuğunuzu etkilemesini istiyorsanız , kullanın {...}
Herhangi bir yan etkiyi silmek istiyorsanız,(...)

Örneğin, eğer bir alt kabuk kullanabilirsiniz:

  • değiştirmek isteyen $IFSbirkaç komutlar için, ama değiştirmek istemiyorum $IFSgeçerli kabuk için küresel
  • cdbir yerde, ancak $PWDşu anki kabuğu için değiştirmek istemiyorum

Parantezlerin bir işlev tanımında kullanılabileceğini not etmek faydalı olacaktır:

  • normal kullanım: ayraçlar: fonksiyon gövdesi geçerli kabukta çalışır; fonksiyon tamamlandıktan sonra yan etkiler devam eder

    $ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /tmp
    $ echo "${#files[@]}"
    11    
    
  • sıradışı kullanım: parantez: işlev gövdesi bir alt kabukta yürütülür; alt kabuk çıkınca yan etkiler yok olur

    $ cd ; unset files
    $ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /home/jackman
    $ echo "${#files[@]}"
    0
    

belgeleme


11
Yıllarca süren kabuk gelişiminden sonra, alt kabuklarda işlevleri çalıştırmak için parantez kullanabileceğinizi bilmiyordum. Küresel ad alanını kirletmekten kaçınmak için ne harika bir fikir!
l0b0

7
localAnahtar kelimeyi kullanmak, bu kirliliği temizlemek için uzun bir yol kat eder.
glenn jackman

2
Evet, ama her değişkeni yerel olarak bildirmeyi unutmamalısınız ve bu kodu çözmektedir.
l0b0

4
İpucu: Yan etkisi olmayan işlevler istiyorsanız ancak olağandışı işlev bildirim sözdiziminden (hangi kod düzenleyicilerin farkında olamayacağınız) kaçınmak istiyorsanız, işlev bildirimi yerine işlev çağrısında parantez kullanın:pwd; (count_tmp); pwd;
Juve

2
kabuk için ... foo () (:;) foo () {(:;); } Siz sorarsanız böyle bildirir!
anthony

23

Resmi bash belgelerinde :

()

( list )

Parantezler arasına bir komut listesi yerleştirmek, bir alt kabuk ortamı oluşturulmasına ve listedeki komutların her birinin bu alt kabukta yürütülmesine neden olur. Liste bir alt kabukta yürütüldüğünden, alt kabuk tamamlandıktan sonra değişken atamaları etkin kalmaz.

{}

{ list; }

Kıvrımlı ayraçlar arasına bir komut listesi yerleştirmek, listenin geçerli kabuk bağlamında yürütülmesine neden olur. Alt kabuk oluşturulmaz. Aşağıdaki liste noktalı virgül (veya yeni satır) gereklidir.


9

'{}' İçerisindeki kod, mevcut iş parçacığı / işlem / ortamda yürütülür ve değişiklikler daha kısaca belirtilmek üzere korunur ve kod geçerli kapsamda çalıştırılır.
'()' İçindeki kod, yürütmeden sonra atılan ayrı bir alt bash işlemi içinde çalıştırılır. Bu alt süreç genellikle alt kabuk olarak adlandırılır ve yeni, çocuk benzeri bir kapsam olarak düşünülebilir.

Örnek olarak, aşağıdakileri göz önünde bulundurun ...

 ~ # { test_var=test }
 ~ # echo $test_var
 test
 ~ # ( test_var2=test2 )
 ~ # echo $test_var2

 ~ # 

'{}' İle yapılan ilk örnekte değişken, '}' kapanmasından sonra bile hala ayarlıdır, oysaki '()' örneğinde değişken, '()' kapsamı dışında ayarlanmaz.


4

(...)bir alt kabukta kod çalıştırmak için kullanılır. Onbeş kullanılan kod {...}bir alt kabukta kullanılmayacak.

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.