Neden `sort <(ls -l)` çalışıyor ancak `sort <(ls -l)` başarısız oluyor?


32

Bugün bu yazı ile fifo'ya hakkında bir şeyler öğreniyorum: Giriş Named Pipes bahseder, cat <(ls -l).

Kullanarak bazı deneyler yaptım sort < (ls -l), ki bu bir hata çıkar:

-bash: syntax error near unexpected token `('`

Sonra komutta fazladan bir boşluk bıraktım.

Ancak, neden bu ekstra komut bu başarısızlığa yol açacaktır? Yönlendirme sembolü neden yakınında olmalıdır (?


* Nix kabuklarının, Alec'in bahsettiği belirteçleri yaratan boşluklara dayanarak işleri böldüğü not edilmelidir.
piliçler

Yanıtlar:


45

Bu bir değil Çünkü <, şey <()tamamen farklı olan. Buna işlem ikame denir , bir işlemin çıktısını bir diğeri için girdi olarak kullanmanıza izin veren bazı kabukların bir özelliğidir.

>Ve <operatörler ila çıkışını ve girişini yönlendirmek dosyaları . <()Operatör, dosyaları değil komutları (süreçler) ile ilgilenir. Kaçtığında

sort < (ls)

Komutu lsbir alt kabukta çalıştırmaya çalışıyorsunuz (parantezin anlamı budur), ardından bu alt kabuğu bir giriş dosyası olarak geçirmek için sort. Ancak bu, sözdizimi kabul edilmez ve gördüğünüz hatayı alırsınız.


3
Cevabınız iyi, ancak then sort is attempting to read the subshell as its input file→ bu açıkça yanlış, çünkü Bash sözdizimini bile çözümlemeyecek. Ne lsde ne sortaslında çalıştırılır.
sleblanc

1
@sebleblanc fuar noktası, cevabı değiştirdi, teşekkürler.
terdon

1
Bu durumda alt kabuk yok. < (ls)burada geçerli bir simge değil.
cuonglm 12:15

@ cunonglm hayır, çünkü bash bunu bir sözdizimi hatası olarak görür. Demek (ls)istediğim , bu lsdenizaltıda koşuyor .
terdon

22

Çünkü öyle olması gerekiyordu.

<(...)içinde bashişlem değiştirme sözdizimi var. İçindeki aynı operatörden kopyalandı ksh.

<, (, ), |, &, ;Özel sözcük belirteçleri olan bashfarklı kombinasyonlarda özel operatörler oluşturmak için kullanılır. <, <(, <<, <&... her biri kendi rolü vardır. <yönlendirme içindir. <file, < filegirdiyi bir dosyadan yönlendirir. <'(file)'girişi bir dosyadan yönlendirir (file), ancak <(file)yönlendirme operatörü olmayan farklı bir operatördür.

< (file)<takip ederdi (file). Bu bağlamda, içinde bash, (file)geçerli değil. (...)gibi bazı bağlamlarda tek bir simge olarak geçerli olabilir:

(sub shell)
func () {
  ...
}
var=(foo bar)

Ama içinde değil

sort < (cmd)

In fishkabuk, durum farklı. Olarak fish, (...)komut ikame (eşdeğer için $(...)de bash). Ve <Bourne benzeri kabuklarda gibi girdi yönlendirme içindir.

Yani içinde fish:

sort <(echo file)

aynı olurdu:

sort < (echo file)

Yani:

sort < file

Fakat bu, bashişlemin ikamesinden tamamen farklı bir şey .

Olarak yashkabuk, bir POSIX kabuğu <(...)için değil işlem ikame ama için işlem yönlendirme

Orada,

sort <(ls -l)

İçin kısa:

sort 0<(ls -l)

bir yönlendirme operatörüdür. Bu aşağı yukarı eşdeğerdir:

ls -l | sort

İken bash, <(ls -l)bu yüzden bir daha gibi, bir borunun yoluna genişletilir:

ls -l | sort /dev/fd/0

İçinde zsh, (...)bir genelleme işleci olarak ( (*.txt|*.png)genişler txtve pngdosyalar *(/)genişler ) ve glob niteleyicisi ( örneğin, dizin dosyalarına genişler ) aşırı yüklenir .

İçinde zsh, içinde:

sort < (ls -l)

Bu (ls -l)bir glob niteleyicisi olarak değerlendirilir. lBağlantıların sayısına maç için ve sonra bir sayı bekliyor eleme glob l(olduğu gibi ls -ld ./*(l2), 2 bağlantıları olan dosyaları listelemek olurdu) böylece eğer bir olsun neden en zsh: number expectedhatayı orada.

sort < (w)zsh: no matches found: (w)bunun yerine (w), yazılabilir boş addaki dosyalarla eşleşmesi yerine bir hata vermiş olur .

sort < (w|cat)Geçerli dizindeki wve / veya catdosyaların içeriğini sıralardı ...


neden sort < $(ls -l)bu hatayı veriyor:bash: $(ls -l): ambiguous redirect
Edward Torvalds

@ edwardtorvalds, çünkü $(ls -l)birden fazla sözcüğe genişler. Split + glob ( sort < "$(echo file)") işlevini önlemek için tırnak kullanın . Davranışın ya da bashPOSIX'in davranışından farklı olduğunu, bu bash öğesinin etkileşimli olmadığında da (+ olduğu gibi çağrılmadığında sh) oradaki split + glob'u yaptığına dikkat edin .
Stéphane Chazelas 21:15

bakarak ls -l | sort /dev/fd/0ben o çıktı söyleyebiliriz ls -lsaklanır /dev/fd/0ve sortkomut istenilen çıktıyı vermek okur. tail -f --retry /dev/fd/0Bu dosyayı izlemek için kullanıyorum ancak çıktı alamıyorum. niye ya? bu dosyayı nasıl okuyabilirim?
Edward Torvalds

Balıklarda, (foo | psub)girdi işlem ikamesini elde etmek için kullanabilirsiniz ; Henüz çıktı işlemi ikamesinin yerine (ha) yoktur.
Zanchey
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.