Có lệnh nào giống như đồng hồ ăn trưa hay hay không


287

Tôi muốn xem một thư mục trên máy Mac của mình (Snow Leopard) và sau đó thực thi một tập lệnh (đặt tên tệp của những gì vừa được chuyển vào một thư mục (dưới dạng tham số ... x.sh "tên tệp")).

Tôi có một tập lệnh được viết bằng bash (x.sh) sẽ di chuyển một số tệp và nội dung khác vào đầu vào $ 1 Tôi chỉ cần OSX cung cấp cho tôi tên tệp khi tệp / thư mục mới được di chuyển / tạo vào thư mục.

Bất kỳ lệnh nào?


1
Bạn nên hỏi làm thế nào DropBox làm điều đó vì có lẽ họ đã thử tất cả các tùy chọn có sẵn.
Jeff Burdges

2
@JeffBurdges Tôi không chắc chắn rằng đó là một công việc dễ dàng. Tuy nhiên, tôi sẽ nói sau khi lướt qua Tài liệu tham khảo FSEvents của Apple, sẽ thật ngớ ngẩn nếu Dropbox không sử dụng điều này. Việc fswatchsử dụng được trình bày như một câu trả lời dưới đây trong thực tế sử dụng phương pháp này.
Steven Lu

Câu trả lời:


446

fswatch

fswatch là một chương trình nhỏ sử dụng API Mac OS X FSEvents để theo dõi một thư mục. Khi nhận được một sự kiện về bất kỳ thay đổi nào đối với thư mục đó, lệnh shell được chỉ định sẽ được thực thi bởi/bin/bash

Nếu bạn đang sử dụng GNU / Linux, inotifywatch (một phần của inotify-toolsgói trên hầu hết các bản phân phối) cung cấp chức năng tương tự.

Cập nhật: fswatch hiện có thể được sử dụng trên nhiều nền tảng bao gồm BSD, Debian và Windows.

Cú pháp / Một ví dụ đơn giản

Cách mới có thể xem nhiều đường dẫn - cho các phiên bản 1.x trở lên :

fswatch -o ~/path/to/watch | xargs -n1 -I{} ~/script/to/run/when/files/change.sh

Lưu ý: Đầu ra số của -osẽ được thêm vào cuối xargslệnh nếu không cho -I{}. Nếu bạn chọn sử dụng số đó, đặt {}bất cứ nơi nào trong lệnh của bạn.

Cách cũ hơn cho các phiên bản 0.x :

fswatch ~/path/to/watch ~/script/to/run/when/files/change.sh

Cài đặt với Homebrew

Kể từ ngày 9/12/13, nó đã được thêm lại vào homebrew - yay! Vì vậy, hãy cập nhật danh sách công thức của bạn ( brew update) và sau đó tất cả những gì bạn cần làm là:

brew install fswatch

Cài đặt không có Homebrew

Nhập các lệnh này vào Terminal.app

cd /tmp
git clone https://github.com/alandipert/fswatch
cd fswatch/
make
cp fswatch /usr/local/bin/fswatch

Nếu bạn không có ctrình biên dịch trên hệ thống của mình, bạn có thể cần cài đặt các công cụ dòng lệnh Xcode hoặc Xcode - cả hai đều miễn phí. Tuy nhiên, nếu đó là trường hợp, có lẽ bạn chỉ nên kiểm tra homebrew .

Tùy chọn bổ sung cho fswatchphiên bản 1.x

Usage:
fswatch [OPTION] ... path ...

Options:
 -0, --print0          Use the ASCII NUL character (0) as line separator.
 -1, --one-event       Exit fsw after the first set of events is received.
 -e, --exclude=REGEX   Exclude paths matching REGEX.
 -E, --extended        Use exended regular expressions.
 -f, --format-time     Print the event time using the specified format.
 -h, --help            Show this message.
 -i, --insensitive     Use case insensitive regular expressions.
 -k, --kqueue          Use the kqueue monitor.
 -l, --latency=DOUBLE  Set the latency.
 -L, --follow-links    Follow symbolic links.
 -n, --numeric         Print a numeric event mask.
 -o, --one-per-batch   Print a single message with the number of change events.
                       in the current batch.
 -p, --poll            Use the poll monitor.
 -r, --recursive       Recurse subdirectories.
 -t, --timestamp       Print the event timestamp.
 -u, --utc-time        Print the event time as UTC time.
 -v, --verbose         Print verbose output.
 -x, --event-flags     Print the event flags.

See the man page for more information.

Hướng dẫn hoặc cài đặt của bạn mà không có homebrew dường như không hoạt động nữa. makeném một lỗi về việc không tìm thấy một tệp thực hiện. May mắn thay, fswatch hiện đã có trên MacPorts, vì vậy sudo port install fswatchhoạt động, đối với những người trong chúng ta sử dụng MacPorts thay vì Homebrew.
coredumperror

Nếu bạn đang sử dụng một lệnh với các đối số tĩnh (ví dụ: tôi đang chạy thử nghiệm đơn vị của mình trên src và các thay đổi thử nghiệm) thì điều này có thể không hiệu quả với bạn. Câu hỏi này ( stackoverflow.com/questions/25689589/ - ) là phần thứ hai tôi cần.
jskulski 21/07/2015

4
Tôi nghe thấy bạn ngoài đó:fswatch ./ | xargs -I{} cp {} ~/Dropbox/backup/latest/
fionbio

fswatch tốt hơn các công cụ như entr hoặc when_changed, có một số lỗi khi xử lý thư mục .git. fswatch chuyên nghiệp hơn nhiều. Đơn giản, bạn fswatch .sẽ chỉ theo dõi thư mục hiện tại.
ẩn danh

Tôi sẽ đề nghị fswatch -0 -v -o /path/to/watched/files | xargs -0 -n 1 -I {} [your command]với -0NULL. Cái này hoạt động với tôi để biên dịch ít hơn
boldnik

95

Bạn có thể sử dụng launchd cho mục đích đó. Launchd có thể được cấu hình để tự động khởi chạy chương trình khi đường dẫn tệp được sửa đổi.

Ví dụ, cấu hình launchd config sau đây sẽ khởi chạy chương trình /usr/bin/loggerkhi thư mục máy tính để bàn của tài khoản người dùng của tôi bị sửa đổi:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>logger</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/logger</string>
        <string>path modified</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/sakra/Desktop/</string>
    </array>
</dict>
</plist>

Để kích hoạt cấu hình, hãy lưu nó vào thư mục LaunchAgents trong thư mục Thư viện của bạn dưới dạng "logger.plist".

Từ shell, sau đó bạn có thể sử dụng lệnh launchctlđể kích hoạt logger.plist bằng cách chạy:

$ launchctl load ~/Library/LaunchAgents/logger.plist

Thư mục máy tính để bàn hiện đang được theo dõi. Mỗi khi nó được thay đổi, bạn sẽ thấy một đầu ra trong system.log (sử dụng Console.app). Để hủy kích hoạt logger.plist, hãy chạy:

$ launchctl unload ~/Library/LaunchAgents/logger.plist

Các tập tin cấu hình ở trên sử dụng WatchPathstùy chọn. Ngoài ra, bạn cũng có thể sử dụng QueueDirectoriestùy chọn. Xem trang man launchd để biết thêm thông tin.


1
Có cách nào để nó theo dõi sự thay đổi trong nội dung tệp cũng như đường dẫn tệp không?
Cam

2
Tôi không nghĩ vậy. Bạn có thể sử dụng opensnoop cho mục đích đó.
Luân xa

1
Tôi đã làm điều này để hoạt động, nhưng sau đó khi tôi chuyển đổi /usr/bin/loggervới tập lệnh Bash của mình và xóa "<string>path modified</strong>"mục nhập, tôi không thể tìm thấy bất kỳ cách nào để tập lệnh bash của tôi biết tập tin nào trên máy tính để bàn của tôi đã bị sửa đổi - chỉ là sự kiện đã xảy ra. Tôi đã cố gắng nhìn vào $0, $1và chỉ có tên kịch bản, lưu ý đến nó.
Volomike

Ngoài ra, điều này có đi vào một vòng lặp một khi nó phát hiện ra một sự thay đổi, thay vì chỉ khởi chạy (và dừng lại) khi nó phát hiện ra một sự thay đổi? Tôi muốn nó hoạt động theo yêu cầu, không tiếp tục chạy trong một vòng lặp cho tôi biết, ví dụ, 2 ngày trước, một cái gì đó đã thay đổi trên máy tính để bàn của tôi, viết nó trong nhật ký nhiều lần. Vì vậy, chúng ta có cần sử dụng một số loại tùy chọn trong khoảng này không?
Volomike

Công việc tuyệt vời và giải thích
ChenSmile

37

Facebook của người canh gác , sẵn qua Homebrew, cũng có vẻ tốt đẹp. Nó cũng hỗ trợ lọc:

Hai dòng này thiết lập đồng hồ trên thư mục nguồn và sau đó thiết lập trình kích hoạt có tên "buildme" sẽ chạy một công cụ có tên "minify-css" mỗi khi thay đổi tệp CSS. Công cụ sẽ được thông qua một danh sách các tên tệp đã thay đổi.

$ watchman watch ~/src

$ watchman -- trigger ~/src buildme '*.css' -- minify-css

Lưu ý rằng đường dẫn phải tuyệt đối.


1
Đây là công cụ tốt nhất.
BentOnCoding

1
Đây là một chương trình nhỏ rất hay: Các tài liệu rất hay, nó không mở một vòng lặp vô hạn (đó là những gì fswatch dường như làm) và nó nhớ những chiếc đồng hồ bạn đã tạo sau khi khởi động lại và tự động khởi động lại chúng.
Brad

21

Bạn có thể muốn xem (và có thể mở rộng) công cụ nhỏ của tôi kqwait. Hiện tại nó chỉ ngồi xung quanh và chờ đợi một sự kiện ghi trên một tệp duy nhất, nhưng kiến trúc kqueue cho phép xếp chồng sự kiện phân cấp ...


Hoạt động cho đến nay trên sư tử núi. Rất đẹp!
Scott

Vì vậy, điều này thực sự tuyệt vời. Tôi gặp một vấn đề nhỏ với fswatch(điều này cũng tốt, vì nó là một trình bao bọc nhẹ như vậy, nó cũng có thể được sửa đổi để làm điều đúng đắn tôi chắc chắn) nơi nó sẽ phát sáng khi chạy những thứ như git status(thực sự chạy mỗi khi zsh lời nhắc được hiển thị trên máy của tôi ...) thực sự tạo ra kịch bản phức tạp mà tôi có bằng cách tạo một vòng phản hồi vô tận. Tuy nhiên, kqwait cung cấp thông tin về tệp đã thay đổi và không bị vấp git status. Tôi cần nó để bắn vào mặc dù viết.
Steven Lu

2
$ brew install kqwait && while true; do kqwait doc/my_file.md; make; done
Joshua Cook

15

watchdog là API python đa nền tảng để xem tệp / thư mục và nó đã tích hợp công cụ "thủ thuật" cho phép bạn kích hoạt các hành động (bao gồm các lệnh shell) khi xảy ra sự kiện (bao gồm tệp mới được thêm, tệp đã xóa và tệp đã thay đổi).


7

Đây chỉ là đề cập đến entr như là một thay thế trên OSX để chạy các lệnh tùy ý khi các tệp thay đổi. Tôi thấy nó đơn giản và hữu ích.



3

Chỉnh sửa: fsw đã được sáp nhập vào fswatch. Trong câu trả lời này, bất kỳ tài liệu tham khảo nào fswbây giờ nên đọc fswatch.

Tôi đã viết một fswatchthay thế trong C ++ được gọi là fswcó một số cải tiến:

  • Đó là dự án GNU Build System, được xây dựng trên mọi nền tảng được hỗ trợ (OS X v.> = 10.6) với

    ./configure && make && sudo make install
    
  • Nhiều đường dẫn có thể được chuyển qua dưới dạng các đối số khác nhau:

    fsw file-0 ... file-n 
    
  • Nó kết xuất một bản ghi chi tiết với tất cả các thông tin sự kiện như:

    Sat Feb 15 00:53:45 2014 - /path/to/file:inodeMetaMod modified isFile 
    
  • Đầu ra của nó rất dễ phân tích để fswđầu ra có thể được chuyển sang một quy trình khác.

  • Độ trễ có thể được tùy chỉnh với -l, --latency.
  • Cờ sự kiện số có thể được viết thay vì các văn bản với -n, --numeric.
  • Định dạng thời gian có thể được tùy chỉnh bằng cách sử dụng strftimechuỗi định dạng với -t, --time-format.
  • Thời gian có thể là giờ địa phương của máy (theo mặc định) hoặc thời gian UTC với -u, --utc-time.

Bắt fsw:

fswđược lưu trữ trên GitHub và có thể được sao chép kho lưu trữ của nó:

    git clone https://github.com/emcrisostomo/fsw

Cài đặt fsw:

fsw có thể được cài đặt bằng các lệnh sau:

    ./configure && make && sudo make install

Thêm thông tin:

Tôi cũng đã viết một bài đăng blog giới thiệu nơi bạn có thể tìm thấy một vài ví dụ về cách làm fswviệc.


2

Tác vụ thư mục Apple OSX cho phép bạn tự động hóa các tác vụ dựa trên các hành động được thực hiện trên một thư mục.


9
Vâng tôi biết, tôi đã thử sử dụng nó nhiều lần, chưa bao giờ thành công để nó hoạt động, bạn có thể cho tôi một ví dụ không?
Mint

1
Đó là một liên kết, không phải là một câu trả lời
Dan Rosenstark 2/2/19

2

Cái ngã ba fswatch của tôi cung cấp chức năng inotifywait -mvới ít hơn một chút (không phải chờ đợi, hơn thế nữa! Tôi gặp nhiều rắc rối hơn trên Linux với inotifywait...) đầu ra thân thiện với phân tích cú pháp.

Đây là một cải tiến so với bản gốc fswatchvì nó gửi đường dẫn thực tế của tệp đã thay đổi qua STDOUT thay vì yêu cầu bạn cung cấp một chương trình mà nó tạo ra.

Nó đã trở nên vững chắc khi là nền tảng của một loạt các kịch bản bash đáng sợ mà tôi sử dụng để tự động hóa công cụ.

(đây là ngoài chủ đề) inotifywaittrên Linux, mặt khác, đòi hỏi rất nhiều công cụ trên nó và tôi vẫn chưa tìm ra cách nào tốt để quản lý nó, mặc dù tôi nghĩ một cái gì đó dựa trên node.jscó thể là vé.


1
Phải, ngã ba của fswatch. Là rằng trên Homebrew?
fatuhoku

1
Câu trả lời là không; nhưng họ đang làm việc trên nó . Để cài đặt nó thực sự nhanh chóng chỉ cần brew install https://raw.github.com/mlevin2/homebrew/116b43eaef08d89054c2f43579113b37b4a2abd3/Library/Formula/fswatch.rb
fatuhoku

1

Tôi có GIST cho việc này và cách sử dụng khá đơn giản

watchfiles <cmd> <paths...>

Để minh họa, lệnh sau sẽ lặp lại Hello Worldmỗi khi file1OR file2thay đổi; và kiểm tra khoảng thời gian mặc định là 1 giây

watchfiles 'echo Hello World' /path/to/file1 /path/to/file2 

Nếu tôi muốn kiểm tra cứ sau 5 giây tôi có thể sử dụng -tcờ

watchfiles -t 'echo Hello World' /path/to/file1 /path/to/file2 
  • -vcho phép verbosechế độ hiển thị thông tin gỡ lỗi
  • -qlàm cho watchfilesthực hiện lặng lẽ ( #sẽ được hiển thị để người dùng có thể xem các chương trình đang thực hiện)
  • -qqlàm cho watchfilesthực hiện hoàn toàn lặng lẽ
  • -h cho thấy sự giúp đỡ và sử dụng

https://gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55


0

Tôi đã kết thúc việc này cho macOS. Tôi chắc chắn rằng điều này là khủng khiếp theo nhiều cách:

#!/bin/sh
# watchAndRun
if [ $# -ne 2 ]; then
    echo "Use like this:"
    echo "   $0 filename-to-watch command-to-run"
    exit 1
fi
if which fswatch >/dev/null; then
    echo "Watching $1 and will run $2"
    while true; do fswatch --one-event $1 >/dev/null && $2; done
else
    echo "You might need to run: brew install fswatch"
fi

Tôi không thể tìm ra cú pháp fswatch mà không có thời gian. Điều này gây khó chịu và làm cho kịch bản khó dừng lại.
Dan Rosenstark

0

Nếu bạn muốn sử dụng NodeJS, bạn có thể sử dụng gói có tên chokidar (hoặc chokidar-cli thực sự) để xem và sau đó sử dụng rsync(kèm theo Mac):

Lệnh Rsync:

$ rsync -avz --exclude 'some-file' --exclude 'some-dir' './' '/my/destination'

Chokidar cli (được cài đặt trên toàn cầu qua npm):

chokidar \"**/*\" -c \"your-rsync-command-above\"


-3

Đây là một thay thế một dòng đơn giản cho người dùng không có watchlệnh muốn thực thi lệnh cứ sau 3 giây:

while :; do your-command; sleep 3; done

Đó là một vòng lặp vô hạn về cơ bản giống như làm như sau:

watch -n3 your-command


3
Điều này KHÔNG giống như sử dụng một thư viện lắng nghe các sự kiện từ hệ thống tập tin. Nếu trong ví dụ của bạn, your-commandI / O đĩa, thì đó là đĩa được bảo đảm đọc / ghi cứ sau 3 giây - hoặc 10.800 lần mỗi giờ. Bằng cách sử dụng các sự kiện hệ thống tập tin, bạn sẽ được đảm bảo rằng I / O (và các hoạt động đắt tiền khác) chỉ xảy ra khi bạn thay đổi một tệp (thường chỉ vài lần một giờ.)
Noah Sussman

Đúng, và tốt để xem xét. Tôi thường cần watchmọi thứ trong một khoảng thời gian tạm thời để xem những gì đang làm. Tôi không sử dụng kỹ thuật được đề cập của mình cho các ứng dụng sản xuất hoặc bất cứ thứ gì tương tự. Ví dụ, tôi muốn xem tiến trình ddvà kỹ thuật của tôi làm cho điều đó xảy ra (thay thế your-commandkhi thích hợp để gửi tín hiệu phù hợp đến dd).
trusktr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.