Có một quy tắc đệm chung theo sau là thư viện I / O tiêu chuẩn C ( stdio
) mà hầu hết các chương trình unix sử dụng. Nếu đầu ra đi đến một thiết bị đầu cuối, nó được tuôn ra ở cuối mỗi dòng; mặt khác, nó chỉ bị xóa khi bộ đệm (8K trên hệ thống Linux / amd64 của tôi; có thể khác với bộ đệm của bạn).
Nếu tất cả các tiện ích của bạn đi theo quy tắc chung, bạn sẽ thấy đầu ra chậm trễ trong tất cả các ví dụ của bạn ( cat|sed
, cat|tr
và cat|tr|sed
). Nhưng có một ngoại lệ: GNU cat
không bao giờ đệm đầu ra của nó. Nó không sử dụng stdio
hoặc nó thay đổi stdio
chính sách đệm mặc định .
Tôi có thể khá chắc chắn rằng bạn đang sử dụng GNU cat
chứ không phải một số unix khác cat
vì những người khác sẽ không hành xử theo cách này. Unix truyền thống cat
có một -u
tùy chọn để yêu cầu đầu ra không có bộ đệm. GNU cat
bỏ qua -u
tùy chọn này vì đầu ra của nó luôn không có bộ đệm.
Vì vậy, bất cứ khi nào bạn có một đường ống cat
ở bên trái, trong hệ thống GNU, việc truyền dữ liệu qua đường ống sẽ không bị trì hoãn. Các cat
thậm chí không được đi từng dòng - thiết bị đầu cuối của bạn được làm điều đó. Trong khi bạn đang nhập dữ liệu cho mèo, thiết bị đầu cuối của bạn ở chế độ "chính tắc" - dựa trên dòng, với các phím chỉnh sửa như backspace và ctrl-U cung cấp cho bạn cơ hội chỉnh sửa dòng bạn đã nhập trước khi gửi Enter.
Trong cat|tr|sed
ví dụ, tr
vẫn nhận được dữ liệu cat
ngay sau khi bạn nhấn Enter, nhưng tr
tuân theo stdio
chính sách mặc định: đầu ra của nó sẽ chuyển sang một đường ống, do đó, nó không tuôn ra sau mỗi dòng. Nó ghi vào ống thứ hai khi bộ đệm đầy hoặc khi nhận được EOF, tùy theo cái nào đến trước.
sed
cũng tuân theo stdio
chính sách mặc định, nhưng đầu ra của nó sẽ đến một thiết bị đầu cuối nên nó sẽ ghi từng dòng ngay sau khi hoàn thành. Điều này có ảnh hưởng đến số lượng bạn phải nhập trước khi có thứ gì đó xuất hiện ở đầu kia của đường ống - nếu sed
bị chặn bộ đệm đầu ra của nó, bạn phải nhập gấp đôi (để điền vào tr
bộ đệm đầu ra và sed
đầu ra của đệm).
GNU sed
có -u
tùy chọn vì vậy nếu bạn đảo ngược thứ tự và sử dụng, cat|sed -u|tr
bạn sẽ thấy đầu ra xuất hiện lại ngay lập tức. ( sed -u
Tùy chọn có thể có sẵn ở nơi khác nhưng tôi không nghĩ đó là truyền thống unix cổ đại như cat -u
) Theo như tôi có thể nói không có tùy chọn tương đương cho tr
.
Có một tiện ích được gọi là stdbuf
cho phép bạn thay đổi chế độ đệm của bất kỳ lệnh nào sử dụng stdio
mặc định. Nó hơi mong manh vì nó sử dụng LD_PRELOAD
để hoàn thành một cái gì đó mà thư viện C không được thiết kế để hỗ trợ, nhưng trong trường hợp này nó dường như hoạt động:
cat | stdbuf -o 0 tr '[:lower:]' '[:upper:]' | sed 'p'
cat
bộ đệm cho đến khi stdin đóng lại.