Tôi muốn tự động chạy tập lệnh bất cứ khi nào tập tin mới được sao chép vào một thư mục cụ thể. Nói cách khác, Linux có cách nào để "xem" một thư mục để thay đổi và sau đó chạy một cái gì đó để đáp ứng với sự thay đổi không?
Tôi muốn tự động chạy tập lệnh bất cứ khi nào tập tin mới được sao chép vào một thư mục cụ thể. Nói cách khác, Linux có cách nào để "xem" một thư mục để thay đổi và sau đó chạy một cái gì đó để đáp ứng với sự thay đổi không?
Câu trả lời:
Nếu bạn đủ may mắn để được phân phối dựa trên debian , apt-get install dnotify
. Các bản phân phối khác có thể có một cái gì đó tương tự - tìm dnotify
tên.
dnotify là một chương trình đơn giản dựa trên API dnotify của Linux kernel 2.4.19 +. dnotify có thể thực thi một lệnh được chỉ định mỗi khi nội dung của một thư mục cụ thể thay đổi. Nó được chạy từ dòng lệnh và nhận hai đối số: một hoặc nhiều thư mục để giám sát và một lệnh để thực thi bất cứ khi nào một thư mục đã thay đổi. Tùy chọn kiểm soát những sự kiện sẽ kích hoạt: khi một tệp được đọc trong thư mục, khi một tệp được tạo, xóa và vv.
Nếu bạn muốn xử lý việc này trong chương trình của riêng bạn, thì dnotify cũng là API bạn muốn sử dụng.
emerge inotify-tools
Bạn có thể chạy một tập lệnh với các công cụ inotify, đại loại như thế này. Nó sẽ xem thư mục để thay đổi các tệp đã sửa đổi, tệp mới và tệp bị xóa, sau đó nó sẽ thực thi tập lệnh.
#!/bin/sh
while inotifywait -e modify -e create -e delete /home/me/code; do
rsync [options] /home/me/code/ /media/nfs/code/
done
incron về cơ bản là những gì bạn muốn, tôi nghĩ. Nó sử dụng inotify làm cơ chế thông báo (như những gì người khác đã chỉ ra, thay thế cho dnotify), nhưng không yêu cầu một tập lệnh liên tục chạy, sử dụng inotifywait hoặc tương tự (mặc dù, rõ ràng, trình nền incron đang chạy mọi lúc). 'Crontabs' trên toàn hệ thống và 'crontabs' trên toàn hệ thống được hỗ trợ theo cách tương tự như cron tiêu chuẩn, nhưng thay vì chỉ định thời gian làm trình kích hoạt, inotify sự kiện và tên tệp / thư mục được sử dụng.
incron được đóng gói cho nhiều bản phân phối, bao gồm Ubuntu và Debian, tôi tin thế.
entr là công cụ thông báo tập tin đơn giản và dễ kết hợp nhất mà tôi đã thấy. Việc sử dụng nó được tối ưu hóa để xem các tập tin hơn là các thư mục, nhưng nó cũng có thể giải quyết trường hợp của bạn.
Để phát hiện và hành động trên tệp đã thêm, hãy kết hợp nó với các công cụ khác như vd make
. entr
không gửi tên hoặc bất cứ thứ gì tương tự, nó chỉ đơn giản là chạy những gì bạn bảo nó chạy.
Để kiểm tra các tập tin được thêm vào trong một thư mục:
## entr exits with rc=0 when terminated
## rc=1 when watched files go away or don't exist to begin with
## rc=2 when new files arrive in watched directories
until echo /path/to/directory_to_watch | entr -d do_stuff
do sleep 1; done
Nếu bạn cũng muốn hành động khi một tệp hiện có thay đổi:
## Here's why it comes in handy that entr exits when new files are added --
## find gets re-run.
until find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/* |
entr -d do_stuff
do sleep 1; done
... và đó là nơi cơ chế vòng lặp có ích, vì find
biểu thức sẽ chạy lại nếu một tệp được thêm vào.
Nếu bạn muốn xử lý lỗi tốt hơn và muốn đảm bảo mọi thứ chỉ chạy một lần cho mỗi tệp được thêm / xóa, mọi thứ sẽ hơi kỳ quặc, nhưng đối với những trường hợp đơn giản này thì thật tuyệt vời.
EDIT: Nếu bạn muốn làm điều này ở cấp độ hệ thống, đại loại như incron , chỉ cần thêm tập lệnh vào trình quản lý quy trình yêu thích của bạn (như s6 , runit , systemd hoặc sysvinit và bỏ qua vòng lặp:
#!/bin/bash
exec entr -d do_stuff < <(find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/*)
Sự exec
thay thế và quá trình ( <(...)
) rất quan trọng khi chạy từ trình quản lý quy trình, để xử lý tín hiệu đúng cách (nghĩa là lấy vỏ ra khỏi đường đi).