“Boru” nedir ve nasıl “kırılabilir”?


12

resim açıklamasını buraya girin

Ben Xcode bir kez çok fazla "kırık boru" hatası aldım. Şimdi bir borunun tam olarak ne olduğunu merak ediyorum.

"Boru" kavramı nedir ve nasıl "kırılabilir"?


3
Bir boru, çok fazla veri tutan uzun bir tüptür. Borunun alıcı ucu veriyi çekmeyi durdurursa, yedeklemeye başlar ve boru patlar. Bilgisayar, boruya veri gönderen sonun bunun olduğunu bildirir.
Yerde

Yanıtlar:


7

Boru, bir işlemin standart çıktısını diğerinin standart girişine bağlamak için kullanılan bir süreçler arası iletişim (IPC) mekanizmasıdır.

Bir dosyada "pax" kelimesini aramak istediğinizde bir örnek:

cat filename | grep pax

ve evet, grepdosyayı doğrudan yapabileceğinizi biliyorum ama bu nasıl çalıştığını açıklamıyor, değil mi?

Bu, catkomutun standart çıktısını komutun standart girişine bağlar grep. catdosyanın içeriğini standart çıktısına gönderir ve grepdosyasını (bu durumda) standart girdisinden okur. Süreçleri bu şekilde birbirine bağlayarak, istediğiniz sayıda boru segmentinden oluşan kendi araçlarınızı oluşturabilirsiniz. Gibi şeyler:

show_users | grep pax | awk -F: '{print $4}' | tr '[a-z]' '[A-Z]' | cut -c1-20

Bir kırık boru gönderen hala aracılığıyla şeyler göndermeye çalışıyor iken verilerin (genellikle) alıcı bağlantıyı kapattı biridir.

Örneğin, bir çağrı programı aracılığıyla büyük bir dosya gönderirseniz (bir kerede bir sayfa görüntülemek için):

cat myfile | pager

ve sonra a yapın CTRL-BREAK, bu pagerişlemin giriş borusunu catkullanmayı bitirmeden kapatmasına neden olabilir . Bu kırık boruyu almak için bir olasılık.


Bir cursory Google aramasından , bu özel sorun geçici dağıtımlarla ilişkili gibi görünüyor ve verilen çözümler genellikle yazılımınızın çoğundan çıkmayı ve cihazlarınızın çoğunu yeniden başlatmayı içerir.

Bu muhtemelen sorunu Apple'a bildirecek kadar ciddidir. Bu konuda ne kadar şikayetçi olursa, bunu düzeltmek için bir şey yapılması daha olasıdır.


Peki "kırık" boru nedir?
Moshe

pr -e4 -n ten-thousand-lines.c | sed 10qkırık bir boru ile sona erer. İster prrahatsız ediyor o SIGPIPE sinyali başka bir konu var olduğunu söylemek için; sinyalin bir sonucu olarak kolayca çıkabilir (sıfırdan farklı bir çıkış durumu oluşturur).
Jonathan Leffler

Borular do not mutlaka "standart" giriş ve çıkışını bağlayın. Komut satırından doğru olsanız da, herhangi bir G / Ç'yi bir borudan geçirmek programlı olarak mümkündür.
CarlF

2

|Karakter genellikle bir boru denir. Çeşitli UNIX mermilerinde (bildiğim), bir komutun çıkışını diğerinin girişine bağlamak için kullanılabilir.

cat myfile.txt | head

headKomut sadece girişin ilk birkaç satır gösterir. Bu noktada, girdisini kapatır. Bu, girdiyi üreten komut için bir sorun oluşturur. Nereye yazıyor? Bu duruma veya yazma sürecinin okuyucu bitmeden sona erdiğinde, buna "kırık boru" denir.

catKomutun sonsuza dek sürmesini önlemek için UNIX standardı, gönderdiği özel bir sinyali ( SIGPIPE , sinyal 13 ) tanımlar cat. Bu sinyal için varsayılan eylem, işlemi catsonlandıran işlemi öldürmektir .

Kullandığınız uygulama, gördüğünüz küçük açılır pencere iletisini oluşturan SIGPIPE dahil tüm sinyaller için bir sinyal işleyici yükledi.



1

Boru, Unix sistemlerinde bir IPC mekanizmasıdır. Bir borunun iki ucu, bir okuma ucu ve bir yazma ucu vardır. Yazma ucuna yazılan veriler, okunan uçtan okunabilir ve yazıldığı sıraya göre çıkar.

Unix komut satırı dünyasında, borular bir işi yapmak için programları birbirine bağlamanın çok yaygın bir yoludur. Örneğin sed 's/foo/bar/g' fred.txt | grep -e 'bar.*baz', dosyada fred.txtdizenin tüm örneklerini dizeyle değiştirir foo, barardından sonucu barbir dizi karakter izleyen satırları arar , sonra baz.

Bu, elbette, çok yararlı görünmüyor. Ancak eminim ki, özellikle her tür ilginç kullanıma nasıl koyabileceğinizi, özellikle de sizin gibi awkveya perlemrinizde olan programlarınız olduğunda görebilirsiniz .

Boru sistemi en başından beri Unix'in bir parçası olmuştur. Ve boru hattınızdaki bir işlemden çıkılırsa, genellikle boru hattındaki tüm programların çıkmasını istersiniz. Bu, varsayılan olarak, okunan uçtaki işlem gitmişse bir boruya yazan bir işlemin bir SIGPIPEsinyal alacağı anlamına gelir . Ve eğer bu sinyali bloke ederse, writeyine de borunun 'kırıldığını' belirten özel bir hata ile başarısız olur.

Varsayılan SIGPIPEişlem, alan işlemi öldürür. Ve eğer boru hattının 'başı' değilse, her SIGPIPEşey zinciri yukarı doğru ilerletir.

Xcode'un şikayet ettiği şey, kendisine giden bir boru ile bir şeyler yapmak için bazı alt programlara başlaması ve bu alt programın boruyu kırık bırakması beklenmedik bir şekilde öldüğü ..


0

“Kırık” boru, bir ucunun yapıldığı close()ve diğer ucunun okunduğu veya üzerine yazıldığı bir borudur . Örneğin, aşağıdaki kabuk komutunda:

cat foo | less

catSüreç borunun yazma ucunu tutar ve lessişlem birini okuma. Okuyucu işlemi boruyu kapatırsa, boru kırılır (ve dolayısıyla işe yaramaz); yazar işlemi işletim sisteminden "kırık boru" hatasını alır.


1
Aslında, okuyucu kapatırsa sadece "kırılır". Eğer yazar onu kapatırsa ( catbiter bitmez belli olur), okuyucu sadece normal bir dosya sonu görecektir.
Random832

Hata! Kesinlikle haklısın ... Cevabımı güncelleyeceğim.
Michael Trausch
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.