2013-09-24 81 views
5

Cho một tập tin "foo.txt", được tạo ra từ:subshell IO chuyển hướng

$ seq 1 10 > "foo.txt" 

Tôi đang cố gắng để đọc cả hai dòng đầu tiên và cuối cùng của tập tin, và tôi bắt đầu bằng cách chuyển hướng các tập tin vào một subshell, do đó danh sách các lệnh sẽ tiêu thụ các tập tin trong chuỗi - mỗi lệnh tiêu thụ đầu vào từ điểm lệnh cuối cùng đã để lại nó, tôi cho rằng:

$ (head -1; tail -1) < "foo.txt" 
1 
10 

Tuy nhiên, nếu tôi cố gắng cùng với một tạm thời mô tả tập tin, kết quả là không giống nhau:

$ (head -1; tail -1) < <(seq 1 10) 
1 

Câu hỏi:

  1. Tôi không chắc chắn về những gì để đặt tên <(seq 1 10), nhưng sự khác biệt giữa điều này tạm là gì bộ mô tả tệp và thông thường một ("foo.txt"), điều này khiến cho việc thực thi subshell hoạt động khác nhau?

  2. Làm cách nào để đạt được cùng một hành vi chuyển hướng "foo.txt" sang vỏ con, nhưng không có tệp tạm thời - mà không thực sự tạo tệp.

Trả lời

5

Đó chỉ là vấn đề về bộ đệm. Hãy thử:

cat foo.txt | (head -1; tail -1) 

và bạn sẽ (có thể) thấy điều tương tự (đầu tiêu thụ toàn bộ đầu vào). Có lẽ những gì đang xảy ra là đầu hoạt động khác với một tập tin thông thường hơn với một đường ống, và sự thay thế quá trình (đó là tên cho cú pháp <(cmd)) đang tạo ra một đường ống. (Trong Linux, các head từ coreutils GNU làm một lseek để cố gắng đặt lại vị trí tại newline cuối cùng mà nó ra, nhưng lseek không thành công trên một đường ống.)

Cũng thử:

(head -1; tail -1) < <(cat /usr/share/dict/words) 

Ở đây, head chỉ tiêu thụ trang đầu tiên của đầu vào và đuôi thấy dòng cuối cùng của dữ liệu.

Hành vi bạn đang thấy không được xác định rõ, vì không có tiêu chuẩn nào quy định số lượng đầu dữ liệu được phép sử dụng. Nếu bạn thay thế head bằng sh -c 'read line; echo "$line"', thì bạn sẽ nhận được hành vi mong muốn trong mọi trường hợp. (Hoặc viết công cụ của riêng bạn để cung cấp hành vi của head mà bạn muốn - in một số dòng cố định trong khi không tiêu thụ nhiều hơn số đó.)

+1

+1 để được giải thích rất tốt. Tuy nhiên, OP yêu cầu nếu có thể có hành vi như vậy mà không có bất kỳ tệp tạm thời nào. Là nó? Các thử nghiệm của tôi không thành công. – fedorqui

+0

Bằng cách thay thế dòng chữ 'head' bằng' sh -c ', hãy đọc "$ line"' ', hành vi mong muốn có thể được thực hiện mà không cần tệp tạm thời –

+0

+1 Đó là giải thích chính xác mà tôi đang tìm kiếm!Vì bạn đã nói về việc tạo ra những thứ của riêng mình, tôi đã suy nghĩ về việc viết một kịch bản shell của riêng tôi, với một vài người bạn; chúng tôi đang suy nghĩ về một vỏ chức năng bằng cách nào đó, với mô hình phù hợp và tất cả các trickstery rất thú vị nhất (: – Rubens