Tam olarak bash'daki <() (ve zsh'deki = ()) nedir?


36

Bash ile oldukça rahatım ama yakın zamanda bilmediğim bir oyuncu değişikliği ile sonuçlandım.

Tam olarak ne <(<command>)bash nedir? =(<command>)Zsh ile karşılaştırması nasıldır ?

Bunun varsayılan dosya tanımlayıcıları ile ilgisi olduğunu biliyorum. Bilgisayarımda

echo <()

/proc/self/fd/11STDOUT betiğinin bir kopyası olarak bulduğum iadeler , ancak bu hala benim için kafa karıştırıcı görünüyor.

Yanıtlar:


51

Buna işlem ikamesi denir.

<(list)Sözdizimi ortak desteklediği, bir bashve zsh. listPipe ( |) kullanılamazken bir komutun ( ) çıkışını başka bir komuta geçirmek için bir yol sağlar . Örneğin, bir komut sadece girişi desteklemiyorsa STDINveya birden fazla komutun çıktısına ihtiyacınız varsa:

diff <(ls dirA) <(ls dirB)

<(list)sistem tarafından destekleniyorsa, listbir dosya çıktısını bağlar /dev/fd, aksi takdirde adlandırılmış bir boru (FIFO) kullanılır (bu aynı zamanda sistemin desteğine de bağlıdır; ne manuel ise her iki mekanizma da desteklenmezse ne olur? bir hata). Dosyanın adı daha sonra komut satırında argüman olarak iletilir.


zshayrıca, =(list)mümkün olduğu kadar değiştirmeyi de destekler <(list). =(list)Geçici bir dosya ile dosya yerine /dev/fdveya bir FIFO kullanılır. <(list)Programın çıktıda görünmesi gerekiyorsa , bunun yerine kullanılabilir .

ZSH el kitabına göre , nasıl <(list)çalıştığıyla ilgili başka sorunlar da olabilir :

=Her ikisi de bir şekilde yararlıdır /dev/fdve adlandırılmış boru uygulama <(...)dezavantajlara sahiptir. Eski durumda, bazı programlar dosyayı komut satırında incelemeden önce söz konusu dosya tanımlayıcısını otomatik olarak kapatabilir, özellikle de programın setuid çalıştığı gibi güvenlik nedenleri için gerekliyse. İkinci durumda, program dosyayı gerçekten açmazsa, borudan okumaya veya yazmaya çalışmaya çalışan alt kabuk (tipik bir uygulamada, farklı işletim sistemlerinde farklı davranışlar olabilir) sonsuza dek engellenir ve açıkça öldürülmesi gerekir. . Her iki durumda da, kabuk aslında bir boru kullanarak bilgi sağlar, böylece lseek(2)dosyada görünmesini bekleyen programlar (man sayfasına bakın ) çalışmaz.


Bu, MacOS'un neden pfctl -f <(echo "pf rules")hatalı dosya tanımlayıcısı diyeceğini anlamama yardımcı oldu . zsh ve = (echo "pf rules") kullanarak bunun yerine çalışır.
johnnyB

9

Not, bu bir bash cevabıdır, zsh değil.

Bash'da boru kullanamayacağınız durumlar var:

some_command | some_other_command

borular, boru hattının her bir bileşeni için alt kabuklar ürettiğinden, alt kabuklar çıktığında, güvendiğiniz herhangi bir yan etki ortadan kalkacaktır. Örneğin, bu bağlamda verilen örnek:

cat file | while read line; do ((count++)); done
echo $count

$countdeğişken, mevcut kabukta bulunmadığından boş bir satır görüntüler .

Bir bash işlemi ikamesi , bir dosyadan yaptığınız gibi "some_command" çıktısını okumanızı sağlayarak bu sıkıntıdan kaçınmanıza izin verir

while read line; do ((count++)); done < <(cat file)
# ....................................1.2
echo $count   # the variable *does* exist in the current shell

(1) normal bir giriş yönlendirmesidir. (2), <()işlem ikame sözdiziminin başlangıcıdır .


2
zsh'deki = (cmdlist) bash'deki <(cmdlist) ile hemen hemen aynı etkiye sahiptir, ancak yeniden yönlendirme için cmdlist çıktısı ile geçici bir dosya oluşturur (ve hazır olduğunda siler). Programda arama potansiyel olarak yapıldığında bu iyidir. <(cmdlist), zsh tarafından da bilinir.
Gombai Sándor
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.