2010-08-11 29 views
6

Tôi cần một cách để thực hiện một quy trình giữ một tập tin nhất định mở mãi mãi. Dưới đây là một ví dụ về những gì tôi có cho đến nay:Giữ một tập tin mở mãi mãi trong một tập lệnh bash

sleep 1000 > myfile &

Nó hoạt động cho một nghìn giây, nhưng thực sự không muốn làm cho một số tuyên bố giấc ngủ/vòng phức tạp. This post đề xuất rằng cat giống như sleep cho vô hạn. Vì vậy, tôi cố gắng này:

cat > myfile &

Nó gần như trông giống như một sai lầm phải không? Dường như nó hoạt động từ dòng lệnh, nhưng trong một tập lệnh, kết nối tệp không được mở. Bất kỳ ý tưởng nào khác?

+0

Không khá chắc chắn lý do tại sao bạn cần phải giữ một tập tin mở mãi mãi, nhưng không làm gì? Bạn chỉ giữ một thư mục không bị xóa? –

Trả lời

5

Lý do mà cat>myfile& hoạt động là vì nó chuyển hướng đầu vào tiêu chuẩn vào tệp.

nếu bạn khởi chạy nó bằng dấu và (ở chế độ nền), nó sẽ không nhận được bất kỳ đầu vào nào, bao gồm phần cuối tệp, có nghĩa là nó sẽ mãi mãi chờ và không in được tệp đầu ra.

Bạn có thể nhận được một hiệu ứng tương đương, trừ KHÔNG phụ thuộc vào đầu vào tiêu chuẩn (sau này là những gì làm cho nó không làm việc trong kịch bản của bạn), với lệnh này:

tail -f /dev/null > myfile & 
+0

Điều đó đã hiệu quả! Tôi vẫn không hiểu tại sao 'con mèo' làm việc trên thiết bị đầu cuối nhưng không phải trong một kịch bản. Trên thiết bị đầu cuối, tôi nhận được thông báo "Ngừng" và tập lệnh không cho tôi điều này. Đó phải là một phần của lý do. – User1

+0

@ User1 - Tôi có thể suy đoán về lý do tại sao mèo không làm việc nhưng thành thật mà nói tôi không biết chắc chắn 100%. Một số loại tương tác SDTIN và tty kỳ lạ, có lẽ. Cảm thấy tự do để hỏi rằng như là một câu hỏi riêng biệt nếu bạn thực sự quan tâm, tôi chắc chắn rằng ai đó sẽ biết các asnwer chắc chắn và tôi muốn được tò mò quá - không có thời gian để điều tra mysefl. – DVK

0
tail -f myfile 

'Làm theo' tệp này và xuất ra bất kỳ thay đổi nào đối với tệp. Nếu bạn không muốn nhìn thấy đầu ra của tail, chuyển hướng đầu ra để /dev/null hoặc một cái gì đó:

tail -f myfile > /dev/null 

Bạn có thể muốn sử dụng tùy chọn --retry, tùy thuộc vào trường hợp cụ thể của bạn. Xem man tail để biết thêm thông tin.

+0

Điều này sẽ không làm những gì anh ta muốn, đó là giữ cho các tập tin mở để viết. Nó sẽ chỉ đọc từ nó. – DVK

+0

@DVK, Anh ấy nói 'giữ tập tin mở', không phải 'để viết'. – strager

+0

Không, nhưng '> myfile' ngụ ý rằng anh ta có nghĩa là viết. –

12

Thay vì sử dụng một quá trình nền, bạn cũng có thể chỉ cần sử dụng bash để mở một trong những mô tả tập tin của nó:

exec 5>myfile 

(việc sử dụng đặc biệt của exec đây cho phép thay đổi chuyển hướng mô tả tập tin hiện tại - xem man bash để biết chi tiết). Thao tác này sẽ mở tệp mô tả 5 thành "myfile" (sử dụng >> nếu bạn không muốn làm trống tệp).

Bạn sau đó có thể đóng tập tin lại với:

exec 5>&- 

(Một nhược điểm có thể của việc này là các FD được thừa hưởng bởi tất cả các chương trình chạy shell trong khi chờ đợi Chủ yếu đây là vô hại - ví dụ của bạn. grep s và sed s thường sẽ bỏ qua FD bổ sung - nhưng nó có thể gây phiền nhiễu trong một số trường hợp, đặc biệt là nếu bạn sinh ra bất kỳ quy trình nào ở xung quanh (vì chúng sẽ giữ FD mở) (

+0

Đây là một tính năng tuyệt vời và thực sự được đánh giá thấp - cảm ơn! –

+1

Điều này thực sự tuyệt vời. Tôi có thể chạy 'exec 3 >>/home/me/myfile' và sau đó chuyển hướng đầu ra từ nhiều tệp sang fd 3 (ví dụ:' grep thing file >> 3') và thêm nhiều thứ vào cùng một tệp mà không phải nhập đường dẫn mỗi lần. Khi tôi hoàn thành, tôi có thể đóng tập tin. Tôi thích nó. Cảm ơn người đàn ông. – vastlysuperiorman

+1

@vastlysuperiorman: Bạn được chào đón! Tôi nghĩ rằng grep của bạn có thể muốn được 'grep điều tập tin> & 3', nhưng có, ý tưởng là âm thanh :) – psmears

1

Trên số cat > myfile & trong terminal vs không chạy như một phần của một script: Trong một không tương tác cô ấy sẽ là stdin của một background command & được chuyển hướng hoàn toàn từ /dev/null.

Vì vậy, cat > myfile & trong một tập lệnh thực sự được dịch sang cat </dev/null > myfile, chấm dứt ngay lập tức cat.

Xem tiêu chuẩn POSIX trên ngôn ngữ Shell lệnh & Asynchronous Lists:

The standard input for an asynchronous list, before any explicit redirections are 
performed, shall be considered to be assigned to a file that has the same 
properties as /dev/null. If it is an interactive shell, this need not happen. 
In all cases, explicit redirection of standard input shall override this activity. 

# some tests 
sh -c 'sleep 10 & lsof -p ${!}' 
sh -c 'sleep 10 0<&0 & lsof -p ${!}' 
sh -ic 'sleep 10 & lsof -p ${!}' 


# in a script 
- cat > myfile & 
+ cat 0<&0 > myfile & 
Các vấn đề liên quan