Awk neden bir pipodan okurken tamponlama yapıyor?


23

Nmea dizeleri gönderen bir gps cihazına bağlı seri bir porttan okuyorum.

Amacımı göstermek için basitleştirilmiş bir çağrı:

  $ awk '{ print $0 }' /dev/ttyPSC9 
  GPGGA,073651.000,6310.1043,N,01436.1539,E,1,07,1.0,340.2,M,33.3,M,,0000*56
  $GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39
  $GPRMC,073651.000,A,6310.1043,N,01436.1539,E,0.42,163.42,070312,,,A*67
  GPGGA,073652.000,6310.1043,N,01436.1540,E,1,07,1.0,339.2,M,33.3,M,,0000*55
  $GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39

Bunun yerine bir borudan okumaya çalışırsam, awk stdout'a göndermeden önce girişi tamponlar.

$ cat /dev/ttyPSC9 | awk '{ print $0 }'
<long pause>
GPGGA,073651.000,6310.1043,N,01436.1539,E,1,07,1.0,340.2,M,33.3,M,,0000*56
$GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39
$GPRMC,073651.000,A,6310.1043,N,01436.1539,E,0.42,163.42,070312,,,A*67
GPGGA,073652.000,6310.1043,N,01436.1540,E,1,07,1.0,339.2,M,33.3,M,,0000*55
$GPGSA,A,3,28,22,09,27,01,19,17,,,,,,2.3,1.0,2.0*39

Tamponlamayı nasıl önleyebilirim?

Düzenleme : Kyle Jones, kedinin çıktısını tamponladığını ancak bunun gerçekleşmediğini belirtti:

$ strace cat /dev/ttyPSC9 | awk '{ print $0 }'
write(1, "2,"..., 2)                    = 2
read(3, "E"..., 4096)                   = 1
write(1, "E"..., 1)                     = 1
read(3, ",0"..., 4096)                  = 2

Düşündüğümde: Bir programın bir terminale yazarken arabelleğe alma işlemini ve diğer tüm durumlar için "normal arabelleğe alma" kullandığını düşündüm. Öyleyse, kedi neden daha fazla tamponlamıyor? Seri port EOF'a sinyal veriyor mu? Öyleyse kedi neden sonlandırılmıyor?


1
BashFAQ 009 yararlı olabilir.
jw013

@ jw013: Bağlantı için teşekkürler, tamponlamanın bashta nasıl çalıştığını gösteren büyük bir özet.
Daniel Näslund

Yanıtlar:


10

Kedilerde değil, awk'de tamponlama olması muhtemeldir. İlk durumda, awk bunun etkileşimli olduğuna inanmaktadır, çünkü girdi ve çıktıları TTY'lerdir (farklı TTY'ler olsalar bile - bu awk'nin bunu kontrol etmediğini tahmin ediyorum). İkincisinde, giriş bir boru olduğundan etkileşimli olmayan bir şekilde çalışır.

Awk programınızda açıkça temizlemeniz gerekecektir. Ancak bu taşınabilir değil.

Çıktının nasıl yıkanacağına ilişkin daha fazla arka plan ve ayrıntılar için, şu adresi okuyun: http://www.gnu.org/software/gawk/manual/html_node/I_002fO-Functions.html


6
Açıklama için teşekkürler. awk -W interactive '{print $0}'hile yapmak gibi görünüyor. Bu 'W interactiveseçenek awk versiyonumda (mawk 1.2) mevcuttur fakat standart bir seçenek olup olmadığını bilmiyorum.
Daniel Näslund

1
@ dannas -Wiçin POSIX standardındaawk değil . Maksimum taşınabilirliğe ihtiyacınız varsa ne yapacağınızdan emin değilim.
jw013

Bu cevabı kabul ediyorum, çünkü awk'ın benim satırımda tamponlama yerine neden tam tamponlama yaptığını açıklıyor - girişin hem çıktı hem de tty olup olmadığını kontrol ediyor. Sadece çıktıyı kontrol edeceğini düşündüm.
Daniel Näslund

@ jw013: Standardı aradığınız için teşekkür ederiz. Benim için sadece awk'nin neden tam tamponlama yaptığını anlamak istedim ve sanırım şimdi yapıyorum.
Daniel Näslund

@ dannas Bunun -W interactiveen azından mawk olan awk'ın Ubuntu 12.04 (ve muhtemelen daha yeni) dağıtımında desteklendiğini onaylayabilirim.
Jason C

37

Bunun eski bir soru olduğunu biliyorum, ancak bir tek gömlek buraya gelmek isteyenlere yardım edebilir:

cat /dev/ttyPSC9 | awk '{ print $0; system("")}'

system("")hile yapar ve POSIX uyumludur. Posix olmayan sistemler: dikkatli olun.

fflush()Aynı olan, ancak awk'nin eski sürümlerinde bulunmayan daha spesifik bir işlev vardır.

Dokümanların kullanımına ilişkin önemli bir bilgi parçası system(""):

gawk, system () işlevinin bu şekilde kullanılmasını özel bir durum olarak görür ve boş bir komutla bir kabuk (veya başka bir komut yorumlayıcısı) çalıştırmayacak kadar akıllıdır. Bu nedenle, gawk ile, bu deyim sadece yararlı değil, aynı zamanda verimlidir.


Bu benim için çalıştı
redolent

3
Benim awkhiçbir şey fflush()de hiçbir şey yapmaz system(""). Benim gawkolsa onurlandırdı.
Krzysztof Jabłoński
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.