Tr için arabelleğe almayı devre dışı bırakabilir miyim


10

trgirişini arabelleğe alıyor gibi görünüyor, böylece bu komut LongRunningCommand|tr \\n ,yalnızca LongRunningCommand'dan birkaç kilobaytlık giriş biriktikten sonra çıktı üretmeye başlayacak.

trBu tamponlamayı veya yeni satırları arabelleğe almadan başka bir karakterle değiştirebilecek herhangi bir komutu durdurmaya zorlamanın bir yolu var mı ?


PS Ben zaten ilk iki öneri denedim Başarıyla boru tamponlama kapatın .


1
stdbufLongRunningCommand'a mı yoksa tr'ye mi yoksa her ikisine de farklı mı başvurdunuz ?
meuh

Her ikisi için de böyle:stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
ndemou

fping -q"Prob başına sonuçları gösterme, sadece son özeti gösterme" diyor, belki de sonunda sadece bir uzun yazma var?
meuh

Hiçbir fping komutu kendi başına iyi çalışmaz. Öneriler için çok teşekkürler
ndemou

2
Ben tamponlama sorunu aslında düşünüyorum çıkışı arasında tr. Dene|stdbuf -i0 -o0 tr ...
meuh

Yanıtlar:


12

Komutlar genellikle girdilerini arabelleğe almaz. read()Büyük bir yığın için bir yapacaklardı , ancak bir borudan okurken, boruda çok fazla bayt yoksa, read()sistem çağrısı var olduğu kadar çok karakterle geri dönecek ve uygulama genellikle .

Buna Bunun önemli bir istisnası olduğunu mawkyeniden tutacak hangi read()girdi tampon dolana kadar ing.

Uygulamalar yine de çıktılarını (stdout) tamponlar . Her zamanki davranış, çıktı bir tty'ye gidecekse, arabelleğe alma satır bazında olacaktır (yani, çıktı için tam bir satır veya çok fazla bir blok dolu olana kadar stdout'a yazmaya başlamayacaktır. uzun satır), diğer her dosya türü için tamponlama bloklarla yapılır (yani, yazmak için bir blok dolu olana kadar yazmaya başlamaz (4KiB / 8KiB gibi bir şey ... yazılım ve sisteme bağlıdır) )).

Bu durumda, LongRunningCommandbüyük olasılıkla çıktısını bloklarla tamponlar (çıktısı bir tty değil bir boru olduğu için) ve trçıktısı muhtemelen terminal olduğu için büyük olasılıkla çıktısını satır satır tamponlar.

Ancak, her yeni satır karakterini çıktısından kaldırdığınızdan, hiçbir zaman bir satır çıkmaz, bu nedenle arabelleğe alma blokla olur.

Burada hem LongRunningCommandve hem de arabelleğe almayı devre dışı bırakmak istiyorsunuz tr. GNU veya FreeBSD sistemlerinde:

stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,

Çizgileri virgülle birleştirmek istiyorsanız, daha iyi bir yaklaşım kullanmak olduğunu unutmayın paste -sd , -. Bu şekilde çıktı yeni satır karakteriyle sonlandırılır (muhtemelen arabelleğe almayı devre dışı bırakmanız gerekir).


@mikeserv. Evet ve stdio buffering kullanan ve setvbuf / setbuffer'ı kendi başına çağırmayan ve bir kabuk yerleşimi değil. Ancak genellikle GNU ve FreeBSD sistemlerinde, tüm bu koşullar yerine getirilir.
Stéphane Chazelas

ah. sadece kendimi birkaç gün önce i statik o benim için / i akışları etkileyemedi hayal kırıklığına uğradım öğrendim sed. sinir bozucu - ama ben genel bilgi olduğunu fark etmedi üzgünüm. Sanırım LD_PRELOAD kullanıyor.
mikeserv

Stéphane'nin ne olduğuna dair kapsamlı açıklama için teşekkürler. Büyük takdir
ndemou

5

İle yeni satır değiştirmek için ",", Çalıştırabileceğiniz

awk '{ printf "%s,", $0 }'

GNU awk ( gawk) ve Solaris nawk, çıkış bir terminale geldiğinde stdin üzerinde satır arabelleğe alma ile çalışır ve tamponlama stdout'u olmadan çalışır. Awk'ınız mawkUbuntu'da gerçekleşiyorsa, ona -W interactiveaynı tamponlama davranışını alma seçeneği verebilirsiniz .

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.