$ () Bir alt kabuk mu?


Yanıtlar:


75

$(…)tanımı gereği alt kabuktur: kabuk çalışma zamanı durumunun bir kopyası ¹ ve alt kabukta yapılan durumdaki değişikliklerin ebeveyn üzerinde etkisi yoktur. Bir alt kabuk genellikle tarafından uygulanan bölmek yeni bir işlem (ancak bazı kabukları, bazı durumlarda bu optimize edebilir).

Değişken değerlerini alabileceğiniz bir alt kabuk değildir. Değişkenlerdeki değişikliklerin ebeveyn üzerinde etkisi olsaydı, bu bir alt kabuk olmazdı. Bu ebeveynin çıktısını alabildiği bir alt kabuktur . Yaratılan alt kabuk $(…), standart çıktısını bir boruya ayarlamıştır ve ana bu borudan okur ve çıktıyı toplar.

Bir deniz kabuğu yaratan başka yapılar da var. Ben bash için tam liste bu olduğunu düşünüyorum:

  • İçin altkabuk gruplama : ( … )) hiçbir şey yapmaz ama bir altkabuk oluşturmak ve sonlandırmak için bekleyin. { … }Hangi grupların sadece sözdizimsel amaçlarla kullandığı ve alt kabuk oluşturmadığı kontrast
  • Arka plan : … &bir alt kabuk yaratır ve sonlandırılmasını beklemez.
  • Pipeline : … | …biri sol taraf için diğeri sağ taraf için olmak üzere iki alt kabuk oluşturur ve her ikisinin de sonlandırılmasını bekler. Kabuk bir boru oluşturur ve sol tarafın standart çıkışını borunun yazma ucuna ve sağ tarafın standart girişini okuma ucuna bağlar. Bazı mermilerde (ksh88, ksh93, zsh, lastpipeseçenek ayarlanmış ve etkin olan bash ), sağ taraf orijinal kabukta çalışır, böylece boru hattı yapısı sadece bir alt kabuk oluşturur.
  • Komut ikame : $(…)(aynı zamanda hecelenen `…`), standart çıkışı bir boruya ayarlanmış olarak bir alt kabuk yaratır, ebeveyndeki çıktıyı toplar ve izleyen eksi satırlarını eksi olarak bu çıktıya doğru genişletir. (Ve çıktı daha fazla bölünmeye ve küreselleşmeye maruz kalabilir, ama bu başka bir hikaye.)
  • Proses ikamesi : <(…)standart çıktısı bir boruya ayarlanmış bir alt kabuk oluşturur ve borunun adına genişler. Ana (veya başka bir işlem) alt kabuk ile iletişim kurmak için boruyu açabilir. >(…)aynısını yapar, ancak standart girişe takılıyken.
  • Coprocess : coproc …bir alt kabuk oluşturur ve sonlandırılmasını beklemez. Alt kabuğun standart giriş ve çıkışlarının her biri, ebeveyn her bir borunun diğer ucuna bağlı olarak bir boruya ayarlanır.

¹ Ayrı bir kabuk çalıştırmanın aksine .


Cevaba da ekler misiniz ${...}?
user1717828

3
@ user1717828 Ne? Neden? Değişken genişlemenin uzaktan bu soru ile ne ilgisi var? Cevabımda tüm kabuk kılavuzunu dahil etmeyeceğim.
Gilles 'SO- kötülük'

1
Değişken genişlemenin uzaktan bu soru ile ne ilgisi var? Bilmiyorum, bu yüzden sordum :-) Bu yüzden küme ayracı değiştirmenin parantez ayracı değiştirmesi gibi bir şey olmadığını tahmin ediyorum.
user1717828

user1717828: değişken genişleme alt kabuklarla ilişkili değildir; tamamen ayrı bir mekanizmadır ve yeni başlıyorsanız kesinlikle okumaya değer!
0xdd,

1
@EnricoMariaDeAngelis Tek yol değil, ama en doğal yol. Başka bir yol command | { read line; … }(kabuğa bağlı olarak line, boru hattından sonra hala mevcut olabilir veya olmayabilir). Tüm yollar bir alt kabuk içerir çünkü çıktı üreten komutun girdiyi okuyan kabuğundan bağımsız olarak çalışması gerekir. Komut tamamen kabuğun içindeyse (yalnızca kabuk yapıları ve yerleşimleri, harici komutlar yoktur), kabuk bir alt işlem oluşturmayabilir, ancak bu yalnızca bir optimizasyondur, yine de bir alt kabuk oluşturur.
Gilles 'SO- kötülükten vazgeçme'

20

Bash 4.4, bash (1) man sayfasından, "GENİŞLETME" bölümünde, "Komut Değiştirme" alt bölümünde:

Bash commandbir denizaltı ortamında yürüterek genişlemeyi gerçekleştirir [...]



1
İlginçtir, CentOS 7 altında bashmanpage herhangi bir alt kabuktan bahsetmez: Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.Bunun kasıtlı bir ihmal olup olmadığını merak ediyorum.
dr01

6
@ dr01 Aksine, bash 4.4 bu cümlenin ifadesini “deniz altı” kelimesini içerecek şekilde değiştirdi. Açıklığa kavuşturuldu: kılavuz açıkça diğer bazı yapıların alt kabuklar olduğunu belirtti, ancak 4.4'e kadar komut değişikliği için açıkça belirtilmedi.
Gilles 'SO- kötülük'

Evet, CentOS v7.4.1708'de (oldukça yeni) bash v4.2.46.
dr01

5

Evet, başka bir işlemde yürütülecek ( commands... )bir bashalt kabuktur commands....

Sahip olduğunuz tek fark $( commands... )bu kod parçası yürütülmesinden sonra olmasıdır commands...şeyi ile değiştirilmesi commands...için yazdım stdout.

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.