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|trvà cat|tr|sed). Nhưng có một ngoại lệ: GNU catkhông bao giờ đệm đầu ra của nó. Nó không sử dụng stdiohoặc nó thay đổi stdiochí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 catchứ không phải một số unix khác catvì những người khác sẽ không hành xử theo cách này. Unix truyền thống catcó một -utùy chọn để yêu cầu đầu ra không có bộ đệm. GNU catbỏ qua -utù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 catthậ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|sedví dụ, trvẫn nhận được dữ liệu catngay sau khi bạn nhấn Enter, nhưng trtuân theo stdiochí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.
sedcũng tuân theo stdiochí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 sedbị chặn bộ đệm đầu ra của nó, bạn phải nhập gấp đôi (để điền vào trbộ đệm đầu ra và sed đầu ra của đệm).
GNU sedcó -utùy chọn vì vậy nếu bạn đảo ngược thứ tự và sử dụng, cat|sed -u|trbạn sẽ thấy đầu ra xuất hiện lại ngay lập tức. ( sed -uTù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à stdbufcho phép bạn thay đổi chế độ đệm của bất kỳ lệnh nào sử dụng stdiomặ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'
               
              
catbộ đệm cho đến khi stdin đóng lại.