2010-03-31 36 views
13

Có trường hợp ... hoặc ngữ cảnh nơi cat file | ... hoạt động khác với ... <file?cat file | ... vs ... <file

+0

Nếu bạn hỏi lý do tại sao bạn thấy một biểu mẫu hoặc hình thức khác được sử dụng ở những nơi khác nhau, nó có vẻ là vấn đề sở thích cá nhân. Kernighan và Pike lưu ý điều này vào năm 1984: http://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X – msw

+1

Thuộc về superuser.com –

Trả lời

9

Khi đọc từ một tệp thông thường, cat chịu trách nhiệm đọc dữ liệu, thực hiện nó theo ý muốn và có thể hạn chế nó theo cách ghi nó vào đường ống. Rõ ràng, bản thân nội dung được bảo tồn, nhưng bất cứ thứ gì khác có thể bị nhiễm độc. Ví dụ: kích thước khối và thời gian đến dữ liệu. Ngoài ra, đường ống tự nó không phải lúc nào cũng trung tính: nó đóng vai trò như một bộ đệm bổ sung giữa đầu vào và ....

cách nhanh chóng và dễ dàng để làm cho vấn đề kích thước khối rõ ràng:

$ cat large-file | pv >/dev/null 
5,44GB 0:00:14 [ 393MB/s] [    <=>         ] 
$ pv <large-file >/dev/null 
5,44GB 0:00:03 [1,72GB/s] [=================================>] 100% 
+1

Thú vị, mặc dù được cho rằng read() sử dụng một bộ đệm hữu hạn, một trong hai cách bạn sẽ nhấn một số quy trình kích thước bộ đệm tối thiểu. strace cho thấy rằng con mèo sử dụng 32kB đọc và pv 128kB trên nền tảng của tôi. – msw

+0

Oh, hey, ví dụ của tôi không thực sự phù hợp với câu hỏi, vì tôi không sử dụng

+0

@msw nó sẽ nhận * rất * phụ thuộc vào việc thực hiện 'cat', nhưng tôi sẽ cố gắng làm cho nó rõ ràng theo một cách khác. –

1

cat file | khởi động chương trình khác (mèo) không bắt đầu trong trường hợp thứ hai. Nó cũng làm cho nó khó hiểu hơn nếu bạn muốn sử dụng "tài liệu ở đây". Nhưng nó sẽ hành xử giống nhau.

4

cat sẽ cho phép bạn nối nhiều tệp theo tuần tự. Nếu không, chuyển hướng <cat file | sẽ tạo ra các tác dụng phụ tương tự.

2

Ống gây ra một subshell được gọi cho lệnh ở bên phải. Điều này cản trở các biến môi trường.

cat foo | while read line 
do 
    ... 
done 
echo "$line" 

so

while read line 
do 
    ... 
done < foo 
echo "$line" 
+0

Cả hai đều cho kết quả tương tự khi tôi thử chúng. –

+0

hiệu ứng phụ thú vị. – pra

+0

@JB: Đặt biến trong vòng lặp, sau đó lặp lại nó sau vòng lặp. Giá trị thay đổi sẽ chỉ tồn tại sau biểu mẫu được chuyển hướng và sẽ không sau biểu mẫu đường ống. Một ví dụ khác là 'cd' bên trong vòng lặp và' pwd' sau vòng lặp. –

4

Bên cạnh những điều đăng bởi những người dùng khác, khi sử dụng chuyển hướng đầu vào từ một tập tin, đầu vào tiêu chuẩn là file nhưng khi đường ống đầu ra của mèo vào đầu vào, đầu vào giữa các ý kiến một luồng với nội dung của tệp. Khi đầu vào tiêu chuẩn là tệp sẽ có thể tìm kiếm trong tệp nhưng đường ống sẽ không cho phép. Bạn có thể thấy điều này bằng cách tìm một file zip và chạy các lệnh sau:

zipinfo /dev/stdin < thezipfile.zip 

cat thezipfile.zip | zipinfo /dev/stdin 

Lệnh đầu tiên sẽ hiển thị các nội dung của zipfile trong khi thứ hai sẽ hiển thị một lỗi, mặc dù nó là một lỗi gây hiểu nhầm vì zipinfo không kiểm tra kết quả của cuộc gọi tìm kiếm và lỗi sau này.

3

A sử dụng vô dụng mèo là luôn tránh. Đó là như lái xe với phanh tay trên. Nó lãng phí chu kỳ CPU cho không có gì, hệ điều hành liên tục chuyển đổi bối cảnh giữa quá trình mèo và tiếp theo trong đường ống. Nếu tất cả những con mèo vô dụng của thế giới đã biến mất và ngừng phát minh, tái phát minh, truyền từ cha sang con, chúng ta sẽ không có sự nóng lên toàn cầu vì chúng ta có thể dễ dàng sống với 1,21 Gigawatt điện được cứu.

Cảm ơn. Bây giờ tôi thấy khá hơn rồi. Hãy tham gia cùng tôi trong cuộc thập tự chinh của tôi để dập tắt việc sử dụng mèo vô dụng trên stackoverflow. Trang web này, theo như tôi nhận thấy nó, một đóng góp lớn cho sự gia tăng của những con mèo vô dụng. Tôi không đổ lỗi cho người mới, nhưng tôi muốn dạy họ. Công nhân và người mới của thế giới, nới lỏng các tay vịn và cứu hành tinh !!! 1!

1

Một sự khác biệt nữa là hành vi chặn open() của tệp đầu vào.

Ví dụ, giả sử đầu vào là một FIFO không có nhà văn, một gọi sẽ không đẻ trứng bất kỳ chương trình con cho đến khi tập tin đầu vào được mở ra, trong khi người kia sẽ đẻ trứng hai quá trình:

prog ... < a_fifo  # 'prog' not launched until shell can open file 
cat a_fifo | prog ... # 'prog' and 'cat' are running (latter may block on open) 

Trong thực tế này hiếm khi các vấn đề ngoại trừ trong hoàn cảnh khó khăn. prog có thể định kỳ đăng nhập hoặc thực hiện một số công việc dọn dẹp trong khi chờ đợi cho đầu vào, ví dụ, mà bạn có thể muốn xảy ra ngay cả khi không có đầu vào có sẵn. (Tại sao không prog đủ tinh vi để mở đầu vào của riêng mình nămo không chặn?)