2010-06-16 31 views
29

Hãy xem xét điều gì đó như:Có OK để sử dụng cùng một tệp đầu vào như đầu ra của lệnh đường ống không?

cat file | command > file 

Thực tiễn này có tốt không? Điều này có thể ghi đè lên các tập tin đầu vào như cùng một thời gian như chúng ta đang đọc nó, hoặc là nó luôn luôn đọc đầu tiên trong bộ nhớ sau đó đường ống đến lệnh thứ hai?

Rõ ràng, tôi có thể sử dụng các file tạm như bước trung gian, nhưng tôi chỉ tự hỏi ..

t=$(mktemp) 
cat file | command > ${t} && mv ${t} file 

Trả lời

44

Không, nó không phải là ok. Tất cả các lệnh trong một đường ống thực hiện cùng một lúc và trình bao chuẩn bị chuyển hướng trước khi thực hiện các lệnh. Vì vậy, có khả năng lệnh sẽ ghi đè lên tập tin trước khi con mèo đọc nó.

Bạn cần sponge(1) từ các chi tiết khác.

+0

cảm ơn, moreutils trông rất hữu ích! Điều tương tự cũng áp dụng cho chuyển hướng: 'lệnh < file > tệp' hoặc thậm chí thay thế tiến trình:' lệnh <(cat file) > tệp'? – Amro

+2

Có, nó cũng áp dụng trong cả hai trường hợp. Hãy nhớ rằng trình bao miễn phí để thiết lập các chuyển hướng theo bất kỳ thứ tự nào, vì vậy bạn nên xem xét hành vi không xác định để truy cập cùng một tệp hai lần trong một lệnh hoặc đường dẫn đơn lẻ. Ngay cả khi nó hoạt động thường xuyên, nó không được đảm bảo. – Juliano

3

Bạn cũng có thể sử dụng một cái gì đó như thế này (không khuyến khích, sử dụng các file tạm rõ ràng trong mã sản xuất):

{ rm file && your_command > file; } < file 
0

Không chỉ cần bạn không nên ghi đầu ra của bạn để đầu vào của bạn, nhưng bạn cũng nên tránh lặp của bạn xuất trở lại đầu vào của bạn.

Khi giao dịch với các tập tin lớn, tôi đã cố gắng

cat *allfastq30 > Sample_All_allfastq30 

và nó tạo ra các thông báo lỗi:

cat: Sample_All_allfastq30: input file is output file 
Các vấn đề liên quan