Borular nasıl anlaşılır


21

Sadece bashta pipo kullandığımda, bunun hakkında daha fazla düşünmedim. Ancak system call pipe () işlevini fork () ile birlikte kullanarak bir C kodu örneği okuduğumda, hem anonim borular hem de adlandırılmış borular dahil olmak üzere boruları nasıl anlayacağımı merak ediyorum.

Sık sık "Linux / Unix'deki her şey bir dosyadır" diye duyulur. Bir borunun gerçekte bir dosya olup olmadığını merak ediyorum, böylece bir kısmı boru dosyasına yazıyor ve diğer kısmı da boru dosyasından okuyor? Eğer öyleyse, isimsiz bir boruya ait boru dosyası nerede oluşturulur? / Tmp, / dev veya ...?

Bununla birlikte, adlandırılmış boru örneklerinden, boruların kullanılmasının geçici dosyaların kullanımına göre alan ve zaman performans avantajına sahip olduğunu da öğrendim, çünkü muhtemelen boruların uygulanmasında yer alan hiçbir dosya yoktur. Ayrıca, borular dosyalar gibi veri depolamıyor gibi görünüyor. Yani bir borunun aslında bir dosya olduğundan şüpheliyim.

Yanıtlar:


23

Performans sorunuzla ilgili olarak, borular IO'ya ihtiyaç duymadığından borulardan daha verimlidir. Bundan cmd1 | cmd2daha verimlidir cmd1 > tmpfile; cmd2 < tmpfile(bu tmpfile, bir RAM diskine veya başka bir bellek cihazına pipe olarak desteklendiğinde doğru olmayabilir ; ancak adlandırılmış bir boru cmd1ise, boru dolu hale geldiğinde çıktısını engelleyebildiği için arka planda çalıştırılmalıdır. ). Sonuçlarına ihtiyacınız varsa cmd1ve yine de çıktısını göndermeniz gerekiyorsa cmd2, diski okuma işlemlerinden kaçınarak paralel olarak çalışacak ve cmd1 | tee tmpfile | cmd2izin vermelisiniz .cmd1cmd2cmd2

Adlandırılmış borular, birçok işlem aynı boruyu okuyup yazıyorsa kullanışlıdır. Bir program, dosya kullanması gereken IO'su için stdin / stdout kullanmak üzere tasarlanmadığında da faydalı olabilir . Dosyaları italik olarak koyarım çünkü adlandırılmış yöneltmeler tam olarak bellekte saklandıkları gibi depolama açısından dosyalar değildir ve bir dosya sistemi girişi olsalar bile (referans amaçlı) sabit bir arabellek boyutuna sahiptirler . Diğer şeylerin sadece düşünmek: UNIX dosya olmadan dosya sistemi girdilerine sahip /dev/nullveya başkaları girdileri /devveya /proc.

Borular (adlandırılmış ve adlandırılmamış) sabit bir tampon boyutuna sahip olduklarından, bunlara okuma / yazma işlemleri engelleyebilir ve okuma / yazma işleminin IOWait durumunda kalmasına neden olabilir. Ayrıca, bir bellek arabelleğinden okurken ne zaman EOF alırsınız? Bu davranışa ilişkin kurallar iyi tanımlanmıştır ve erkekte bulunabilir.

Borularla yapamayacağınız bir şey (adlandırılmış ve adlandırılmamış) verilere geri bakmaktır. Bir bellek tamponu kullanılarak uygulandıkları için bu anlaşılabilir bir durumdur.

Hakkında "everything in Linux/Unix is a file"aynı fikirde değilim. Adlandırılmış kanallarda dosya sistemi girişi vardır, ancak tam olarak dosya değildir. Adlandırılmamış borular, dosya sistemi girişlerine sahip değildir (belki de hariç /proc). Ancak, UNIX'teki çoğu GÇ işlemi, adsız boru (ve soket) dahil olmak üzere bir dosya tanımlayıcısına ihtiyaç duyan okuma / yazma işlevi kullanılarak yapılır . Bunu söyleyebileceğimizi sanmıyorum "everything in Linux/Unix is a file", ama kesinlikle söyleyebiliriz "most IO in Linux/Unix is done using a file descriptor".


Teşekkürler! İki komut bir boru ile birbirine bağlanıyor mu, ikincisi ilk bittikten sonra koşmaya başlasınlar mı?
Tim

Evet, 2 komut paralel olarak çalıştırılır. Onlar ve ilk çıktı tampondan daha fazla olmasaydı, engellenirdi. 2 farklı mermide koşarak cmd1 > fifove cmd2 < fifoadlandırılmış pipoyu yaratarak deneyebilirsiniz mkfifo fifo.
jfg956

Yapabileceğiniz başka bir test, öldürmektir cmd2ederken cmd1: hala çalışıyor cmd1muhtemelen kırık bir boru mesage bildirdiği duracaktır.
jfg956

Teşekkürler! ne demek engellenir? Bu durumda, bloktan sonraki akıştaki tarihin kaybedileceği anlamına mı geliyor?
Tim

2
Veri kayıp değil. Boru tamponu doluysa, cmd1boruya yazma işlemi sadece borudan cmd2veri okuduğunda dönecektir . Aynı şekilde, cmd2bir borudan okunan arabellek boşalıncaya kadar boş kalırsa engellenir cmd1.
jfg956

4

UNIX felsefesinin temel dayanaklarından ikisi:

  1. Bir şeyi iyi yapan küçük programlar yapmak.
  2. ve her programın çıktısının
    henüz bilinmeyen bir programa girdi olmasını bekler .

    Boruların kullanılması, istediğiniz iki
    sonucu elde etmek için son derece güçlü komut zincirleri oluşturmak için bu iki tasarım temelinin etkilerinden yararlanmanızı sağlar .

    Dosyalarda çalışan çoğu komut satırı programı, standart giriş (klavye ile giriş) ve standart çıkış için (
    ekrana yazdırma) giriş kabul edebilir .

    Bazı komutlar sadece bir boru içerisinde çalışacak şekilde tasarlanmıştır, doğrudan dosyalarda çalışamazlar.

    örneğin trkomut

  ls -C | tr 'a-z' 'A-Z'
    cmd1 | cmd2
  • Ekran yerine cmd1'in STDOUT'unu, cmd2'nin STDIN'sine gönderir.

  • STDERR borular boyunca iletilmez.

    Kısacası Pipes is character (|)komutları bağlayabilirsiniz.

    STDOUT'a yazan herhangi bir komut borunun sol tarafında kullanılabilir.

       ls - /etc | less 

    STDIN'den okuyan herhangi bir komut borunun sağ tarafında kullanılabilir.

       echo "test print" | lpr 

    Geleneksel bir boru "adsızdır" çünkü isimsiz olarak bulunur ve işlem devam ettiği sürece devam eder. Adlandırılmış bir boru sistemde kalıcıdır ve işlemin ömrünün ötesinde vardır ve artık kullanılmadığında silinmelidir. İşlemler, süreçler arası iletişimi (IPC) gerçekleştirmek için genellikle adlandırılmış boruya (genellikle bir dosya gibi görünür) eklenir.

kaynak: http://en.wikipedia.org/wiki/Named_pipe


3

Diğer cevapları desteklemek için ...

stdin ve stdout dosya tanımlayıcılarıdır ve okunmuş ve dosya gibi yazılmıştır. bu nedenle bunu yapabilirsiniz echo hi | grep hive yankı stdout'unu bir boru ile değiştirir ve grep stdin'i bu borunun diğer ucuna değiştirir.


1

Her şey bir dosyadır.

İfadeyi tam anlamıyla alırsak, “sadece dosyalarımız var, başka hiçbir şey” anlamına geliriz. Bu doğru yorum değil, ne var.

“Her şey bir dosya” derken, her şeyin bir diske kaydedildiğini söylemiyoruz. Her şeyin bir dosya gibi göründüğünü, okunabileceğini, yazılabileceğini söylüyoruz.

Unix'te, bir dosya veya dosya olmayan bir kez açıldığında, bir dosya gibi ele alınabilir. Ancak, tüm dosyalar tüm işlemleri desteklememektedir. Örneğin, bazı dosyalar (dosya olmayanlar), aramayı desteklemiyorlar: sırayla okunmaları / yazılmaları gerekir (bu, borular ve soketler için geçerlidir).

Her şeyin bir dosya adı vardır (bazı sistemlerde: örneğin Debian Gnu / Linux ve diğer birçok Gnu / Linux).

  • Açık olan tüm dosyalar bir dosya adı alır. Görmek/proc/self/fd/…
  • Ağ soketleri bir dosya adıyla açılabilir; /dev/tcp
    örneğin:cat </dev/tcp/towel.blinkenlights.nl/23

Bu son bölüm yalnızca /procdosya sistemine sahip sistemlerde ve /dev/tcpdosya yapısı sağlayan sistemlerde (veya kabuklarda) geçerlidir .
Kusalananda
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.