Engellemeyen arabellek adı verilen boru?


20

Şüphe duymadığım bir şey arıyorum: Komut satırından kullanmak için bir engelleme arabellek adı verilen pipe (fifo). Böyle bir şey var mı?

İşte kullanım durumu: Arka planda uzun süre çalışacak ve çok fazla çıktı yapacak bir işlemim olduğunu varsayalım stdout. Çıktıyı gerçekten umursamıyorum ve saklamak istemiyorum (belki de yeterli alanım yok), ama periyodik olarak "bırak" ve ne yaptığını takip et, sonra tekrar bırak ve işini yapması için bırakın. Bu yüzden çıktısını bu teorik tamponlu, engellemeyen adlandırılmış boruya yönlendirmek ve daha sonra periyodik olarak ona dokunmak istiyorum.

Yani temelde ( 10Mtampon boyutu olmak) böyle başlamak istiyorum :

mkmagicfifo magicfifo 10M
spewingprocess > magicfifo &

... ve neler olup bittiğini görmek için düzenli olarak uğrayın ...

tail -f magicfifo

... olmadan magicfifo tüm çıktıyı (yani normal bir dosya) saklanması ve olmadan o doldurur ve (böylece, oldukça normal bir adlandırılmış yöneltme) aday değilken o püsküren sürecini engelleme.

Çözümleri içeren tailveya yapamayacağımı düşünmüyorum prune(iyi, ilgili bir geçici çözümü düşünebilirim tail), çünkü tailyine de tüm verileri bir yerde saklamamı gerektirir (eğer onu bırakmak ve bakmaktan vazgeçmek istersem), ve prunedosyayı yeniden yazmak zorunda, muhtemelen (bunu denemedim / kanıtlamamıştım) tüm çıktıyı üreten sürecin yeniden yönlendirmesini kırarak.

Bunu yapmak için bazı yardımcı programı yazabilirim, ama * nix dosyaları ve boruları ve bu kadar çok güzel yönleri vardır, ben sadece yardım edemem ama bunun var olduğunu düşünüyorum ve sadece bunu bilmiyorum.

Yani: Böyle bir şey var mı, eğer öyleyse nedir?


1
Tanımladığınız şey bir "halka tamponu" veya "dairesel tampon" dur. Böyle bir şeyi korumak için herhangi bir komut satırı aracının farkında değilim, ancak oluşturulması önemsiz olurdu.
Shawn J. Goff

2
"Linux blokajsız fifo (isteğe bağlı günlük kaydı)", stackoverflow.com/questions/7360473/… 'de açıklanan çözümlere göz atın .

1
Bu StackOverflow üzerinde çözüldü gibi görünüyor: stackoverflow.com/questions/7360473/…
James Blackburn

@JamesBlackburn: Teşekkürler! Çok ilginç.
TJ Crowder

Yanıtlar:


16

Bence aradığınız şey GNU screen. Bir veya daha fazla programdan son ekranı veya iki çıktıyı tam olarak tutmak için bir arabellek tutar ve bağlantıyı kesip daha sonra geri dönmenizi sağlar.


Ekran önermek için +1. BTW, bunu birçok "geçmiş satırını" tutacak şekilde yapılandırabilirsiniz.
Bay Shunz

1
Teşekkürler. Sorumda gösterdiğim komutlara bunu nasıl uygulayacağınıza dair bir örnek verebilir misiniz? Adam sayfası bir pencere yöneticisi (grafiksel anlamda değil, yine de terminal anlamda demek istediklerini söylüyor). Ve yine de (ssh aracılığıyla) bırakıp gerekirse bırakabilir miyim? (Örn, uzak sunucularda ops.)
TJ Crowder

Evet, GNU ekranını bu şekilde kullanabilirsiniz. Yeni (potansiyel olarak adlandırılmış) bir oturum oluşturur, komutunuzu o oturumun içinde çalıştırır ve bağlantıyı kesersiniz.
TML

2
Ayrıca tmuxve dtach- aynı sınıftaki terminal çoklayıcı / oturum yöneticisi uygulaması aynı şeyi başarabilmelidir.
jw013

5

Kullanabilirsiniz, pvbir boru hattında istediğiniz kadar tamponlama sağlar. Bu şekilde kullanabilirsiniz:

sprewingprocess | pv -B 1g > ordinaryfifo &

Bu size spewingprocessve fifo arasında 1GB'a kadar tamponlama sağlar . Çoğu Linux dağıtımı pv, ister inan ister inanma adlı bir pakette sunar pv.


Teşekkürler, ancak pipe adındaki hedefi okumasaydım tampon dolduğunda bu blok olmaz mıydı?
TJ Crowder

1
Evet, ama başka seçeneğin var mı? Sonlu bir evrende, kelimenin tam anlamıyla sınırsız tamponlama yapamazsınız.
David Schwartz

Diğer seçenek sorumu açıkladığım gibi: Tüm çıktıları saklamamak. Arabellek dolduğunda, en eski şeyler atılır.
TJ Crowder

Hmm, bunu test ettim ve maalesef tamamen çalışmıyor. Eğer fifoyu okuyan işlem bir süreliğine okumayı durdurursa, pv fifoya yazmaya çalışmayı engeller ve çok iş parçacıklı olmadığı için, bu da pv'nin arabelleğine veri okumayı engeller. Yani pv'nin tamponu sadece fifoyu okuyan süreç okumaya devam ederken doldurmaya devam edecektir. pv bazı verileri okuyabilir ve arabelleğe alabilir, ancak yazarın tamamen engellenmesini engellemez.
Daniel S. Sterling

1

Ben de aynı problemi yaşadım. Bu benim ilk çözümüm. Önce çıktıyı her satırdan sonra kestiğimiz bir dosyaya yazın, böylece süresiz olarak büyümez:

spewingprocess | while read line; do echo $line > buffer.txt ; done

Sonra kuyruk kullanarak dosyadan okuyun (burada 2> /dev/null"dosya kesildi" hata iletisinden kurtulur):

tail -f ./buffer.txt 2> /dev/null

Bu şekilde tampon büyümez ve çoğullanabiliriz, örneğin istediğimiz kadar kuyruk çalıştırabiliriz. Bununla birlikte, bu yaklaşımla ilgili sorun, bu testin gösterdiği gibi kuyruktan okuyabildiğinden daha hızlı kesildiğinde veri kaybedebilmemizdir:

for ((i=0; ; i++)) ; do echo "$i" ; done | while read line; do  echo $line > buffer.txt ; done
tail -f ./buffer.txt 2> /dev/null > log.txt

Bir süre koştuktan sonra ilk ve son satırlar:

$ head -n 1 log.txt
0
$ tail -n 1 log.txt
78783

Ancak dosyanın daha az satırı vardır, bu nedenle bazıları kaybolur:

$ wc log.txt
67087  67087 392819 log.txt

Yine de, veri kaybı hakkında çok fazla umursamıyorsanız veya spewingprocess'iniz veri kaybının gerçekleşmesi için yeterince hızlı değilse, güzel bir çözüm gibi görünüyor.

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.