Giải thích đơn giản
Giống như nhiều tiện ích, đây không phải là một thứ gì đó đặc biệt với một chương trình, grep
thay đổi đầu ra tiêu chuẩn của nó giữa được đệm dòng và được đệm hoàn toàn . Trong trường hợp trước, thư viện C đệm dữ liệu đầu ra trong bộ nhớ cho đến khi bộ đệm chứa các dữ liệu đó được điền hoặc ký tự linefeed được thêm vào nó (hoặc chương trình kết thúc sạch), sau đó nó gọi write()
để thực sự ghi nội dung bộ đệm. Trong trường hợp sau, chỉ có bộ đệm trong bộ nhớ trở nên đầy (hoặc chương trình kết thúc sạch) mới kích hoạt write()
.
Giải thích chi tiết hơn
Đây là lời giải thích nổi tiếng, nhưng hơi sai. Trong thực tế, đầu ra tiêu chuẩn không phải là bộ đệm dòng mà là bộ đệm thông minh trong thư viện GNU C và thư viện BSD C. Chuẩn đầu ra là cũng đỏ ửng khi đọc tiêu chuẩn đầu vào làm cạn kiệt của nó đệm trong bộ nhớ (đầu vào trước khi đọc) và thư viện C có gọi read()
để lấy một số đầu vào nhiều hơn và nó được đọc đầu một dòng mới. (Một lý do cho việc này là để ngăn chặn sự bế tắc khi một chương trình khác tự kết nối với cả hai đầu của bộ lọc và hy vọng có thể vận hành từng dòng một, xen kẽ giữa việc ghi vào bộ lọc và đọc từ nó; như "coprocesses" trong GNU awk
ví dụ.)
Ảnh hưởng thư viện C
grep
và các tiện ích khác thực hiện việc này - hoặc, đúng hơn, các thư viện C mà họ sử dụng thực hiện việc này, bởi vì đây là một tính năng được xác định của lập trình bằng ngôn ngữ C - dựa trên những gì họ phát hiện ra đầu ra tiêu chuẩn của họ. Nếu (và chỉ nếu) nó không phải là một thiết bị tương tác, họ chọn bộ đệm đầy đủ, nếu không họ chọn bộ đệm thông minh. Một đường ống được coi là không phải là một thiết bị tương tác, bởi vì định nghĩa là một thiết bị tương tác, ít nhất là trong thế giới của Unix và Linux, về cơ bản là isatty()
cuộc gọi trả về đúng cho bộ mô tả tệp có liên quan.
Giải pháp để vô hiệu hóa bộ đệm đầy đủ
Một số tiện ích như grep
có các tùy chọn idiosyncratic như --line-buffered
thay đổi quyết định này, mà bạn có thể thấy là đặt tên sai. Nhưng một phần nhỏ của các chương trình lọc mà người ta có thể sử dụng thực sự có một tùy chọn như vậy.
Tổng quát hơn, người ta có thể sử dụng các công cụ đào sâu vào các phần bên trong cụ thể của thư viện C và thay đổi việc ra quyết định (có vấn đề về bảo mật nếu chương trình bị thay đổi là set-UID và cũng cụ thể cho các thư viện C cụ thể, và thực tế là cụ thể đối với các chương trình viết bằng hoặc lớp trên đầu trang của ngôn ngữ C), hoặc các công cụ như ptybandage
rằng không thay đổi bên trong của chương trình mà chỉ đơn giản xen một pseudo-thiết bị đầu cuối như đầu ra tiêu chuẩn để quyết định đi ra là "tương tác", để ảnh hưởng đến điều này.
đọc thêm
cat
nối các tập tin. Bạn đang cố gắng làm gì bằng cách dẫn vàocat
?