Tại sao awk làm bộ đệm đầy đủ khi đọc từ một đường ống


23

Tôi đang đọc từ một cổng nối tiếp được kết nối với một thiết bị gps gửi các chuỗi nmea.

Một lời mời đơn giản hóa để minh họa quan điểm của tôi:

  $ 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

Thay vào đó, nếu tôi cố gắng đọc từ một đường ống, hãy đánh thức bộ đệm đầu vào trước khi gửi nó đến thiết bị xuất chuẩn.

$ 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

Làm thế nào tôi có thể tránh được bộ đệm?

Chỉnh sửa : Kyle Jones đề xuất rằng con mèo đang đệm đầu ra của nó nhưng điều đó dường như không xảy ra:

$ 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

Khi tôi nghĩ về nó: tôi nghĩ rằng một chương trình đã sử dụng bộ đệm dòng khi ghi vào thiết bị đầu cuối và "bộ đệm thông thường" cho tất cả các trường hợp khác. Vậy thì, tại sao mèo không được đệm nhiều hơn? Là cổng nối tiếp báo hiệu EOF? Vậy thì tại sao mèo không chấm dứt?


1
BashFAQ 009 có thể hữu ích.
jw013

@ jw013: Cảm ơn liên kết, một tổng hợp tuyệt vời về cách bộ đệm hoạt động trong bash.
Daniel Näslund

Câu trả lời:


10

Nó có khả năng được đệm trong awk, không phải mèo. Trong trường hợp đầu tiên, awk tin rằng nó tương tác vì đầu vào và đầu ra của nó là TTY (mặc dù chúng là các TTY khác nhau - tôi đoán rằng awk không kiểm tra điều đó). Trong lần thứ hai, đầu vào là một đường ống để nó chạy không tương tác.

Bạn sẽ cần phải rõ ràng tuôn ra trong chương trình awk của bạn. Đây không phải là di động, mặc dù.

Để biết thêm thông tin chi tiết về cách tuôn ra đầu ra, hãy đọc: http://www.gnu.org/software/gawk/manual/html_node/I_002fO-Fiances.html


6
Cảm ơn đã giải thích. awk -W interactive '{print $0}'xuất hiện để làm các thủ thuật. Các 'W interactivetùy chọn có sẵn trên phiên bản awk của tôi (mawk 1.2) nhưng tôi dunno nếu đó là một lựa chọn tiêu chuẩn.
Daniel Näslund

1
@dannas -Wkhông có trong tiêu chuẩn POSIX choawk . Tôi không chắc phải làm gì nếu bạn cần tính di động tối đa.
jw013

Tôi chấp nhận câu trả lời này vì nó giải thích tại sao awk thực hiện đệm hoàn toàn trong ví dụ của tôi, thay vì đệm dòng - nó kiểm tra xem đầu vào có phải là tty cũng như đầu ra không. Tôi chỉ nghĩ rằng nó sẽ kiểm tra đầu ra.
Daniel Näslund

@ jw013: Cảm ơn bạn đã tra cứu tiêu chuẩn. Đối với tôi, tôi chỉ muốn hiểu tại sao awk lại thực hiện đệm hoàn toàn và tôi nghĩ tôi làm ngay bây giờ.
Daniel Näslund

@dannas Tôi có thể xác nhận rằng -W interactiveít nhất là được hỗ trợ trong bản phân phối awk của Ubuntu 12.04 (và có lẽ mới hơn), đó là mawk.
Jason C

37

Tôi biết đó là một câu hỏi cũ, nhưng một câu hỏi có thể giúp những người đến đây tìm kiếm:

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

system("")thực hiện các mẹo và tuân thủ POSIX. Hệ thống không posix: hãy cẩn thận.

Tồn tại một chức năng cụ thể hơn fflush()làm tương tự, nhưng không có sẵn trong các phiên bản cũ hơn của awk.

Một thông tin quan trọng từ các tài liệu liên quan đến việc sử dụng system(""):

gawk coi việc sử dụng hàm system () này là trường hợp đặc biệt và đủ thông minh để không chạy shell (hoặc trình thông dịch lệnh khác) với lệnh trống. Do đó, với gawk, thành ngữ này không chỉ hữu ích, nó còn hiệu quả.


Điều này làm việc cho tôi
có hương thơm

3
Tôi awkkhông làm bất cứ điều gì trên không fflush()cũng không system(""). gawkMặc dù vậy, tôi rất vinh dự.
Krzysztof Jabłoński
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.