Xem hệ thống tập tin trong thời gian thực trên OS X và Ubuntu


11

Tôi đang tìm kiếm một công cụ CLI sẽ xem một thư mục và nhổ ra tên của các tệp thay đổi trong thời gian thực.

some_watch_command /path/to/some/folder | xargs some_callback

Tôi biết inotify( inotify-tools?) Và dường như đó là thứ tôi cần, nhưng tôi cần thứ gì đó tương thích cả Linux (trong trường hợp của tôi là Ubuntu) và OSX.

Nó không cần phải nhanh như chớp, nhưng nó cần phải kích hoạt khi thay đổi (trong vòng một giây là hợp lý). Ngoài ra, tôi không nhất thiết cần chương trình CLI chính xác được đề cập ở trên. Nếu một số công nghệ cơ bản tồn tại và có thể dễ dàng viết kịch bản trên cả hai nền tảng thì điều đó cũng sẽ rất tuyệt.


1
Tôi thích fswatchOS X mà tôi tìm thấy trên một câu hỏi được gắn thẻ là trùng lặp - superuser.com/questions/445907/
mẹo

Câu trả lời:


11

OS X thường sử dụng Tác vụ thư mục hoặc Launchd cho tác vụ này.

Công cụ đa nền tảng duy nhất tôi biết là API watchdog cho Python (do đó có sẵn cho OS X và Linux). Cài đặt nó thông qua pip(hoặc easy_install)

pip install watchdog

Nó đi kèm với watchmedocông cụ dòng lệnh, cho phép bạn chạy các lệnh shell trên các sự kiện hệ thống. Kiểm tra cú pháp chung của nó vớiwatchmedo --help

Dưới đây là một ví dụ ngắn, nơi bạn có thể dễ dàng sửa đổi lệnh và đường dẫn được tô đậm:

lệnh watchmedo shell \
    - đáng chú ý
    --command = ' echo "$ {watch_src_path}" ' \
     / some / thư mục

Điều này chỉ đơn giản là nhổ các đường dẫn đến tất cả các tệp hoặc thư mục đã thay đổi, cho phép bạn chuyển watchmedođầu ra của ống sang một lệnh shell khác.


Có vẻ như Tác vụ thư mục có một số hạn chế (và khó kiểm tra nếu không có OSX), nhưng watchmedonó hoạt động hoàn hảo với tôi. Cảm ơn!
Adrian Schneider

2

Tôi đã điều chỉnh một số tập lệnh Ruby mà tôi đã gặp để làm chính xác những gì bạn đang tìm kiếm. Đây là mã Ruby:

#!/usr/bin/ruby
# Inspired by http://vikhyat.net/code/snippets/#watchfile

# How to use:
# This script takes two paramaters:  a folder and a shell command
# The script watches for when files in the folder are changed.  When they are, the shell command executes
# Here are some shortcuts you can put in the shell script:
# %F = filename (with extension)
# %B = base filename (without extension)


unless ARGV.length == 2
  puts "\e[32m    Usage: \e[0mruby OnSaveFolder.rb 'folder' 'command'"
  exit
end

require 'digest/md5'
require 'ftools'

$md5 = ''
$directory = File.expand_path(ARGV[0])
$contents = `ls #{$directory}`
$contentsList = $contents.split("\n")
$fileList = []


Dir.chdir($directory)

for i in $contentsList
  if ( File.file?(File.expand_path(i)) == true)
    $fileList.push(i)
  end
end

$processes = []

def watch(file, timeout, &cb)
  $md5 = Digest::MD5.hexdigest(File.read(file))
  loop do
    sleep timeout
    if ( temp = Digest::MD5.hexdigest(File.read(file)) ) != $md5
      $md5 = temp
      cb.call(file)
    end
  end
end

puts "\e[31m Watching files in folder \e[34m #{$directory}"
puts "\e[32m    Press Control+C to stop \e[0m"

for i in $fileList
  pid = fork do
    $num = 0
    $filePath = File.expand_path(i)

    watch i, 1 do |file|
      puts "\n     #{i} saved"

      $command = ARGV[1].dup
      if ( ARGV[1].include?('%F') )
        $command = $command.gsub!('%F', i)
      end
      if ( ARGV[1].include?('%B') )
        $command = $command.gsub!('%B', File.basename(i, '.*'))
      end

      $output = `#{$command}`
      if ( $output != '')
        puts "\e[34m     #{$command}\e[31m output: \e[0m"
        puts $output
      end
      puts "\e[34m     #{$command}\e[31m finished \e[0m (#{$num}, #{Time.now})\n"
      $num += 1

    end
  end
  $processes.push(pid)
end

Process.wait(pid)

for i in $processes
  `kill #{i}`
end

Tôi đặt tên cho kịch bản này là "OnSaveFolder.rb". Phải có hai tham số: thư mục bạn muốn xem để thay đổi và mã bash bạn muốn chạy khi có thay đổi. Ví dụ,

ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'

Tôi hi vọng cái này giúp được! Tôi đã thấy rằng ruby ​​hoạt động rất tốt cho loại điều này và nó được cài đặt trên OS X theo mặc định.


Đã cho nó một shot nhưng hơi khó để điều chỉnh mà không có bất kỳ nền tảng Ruby nào. Dẫu sao cũng xin cảm ơn!
Adrian Schneider

điều đó thật tuyệt. Bất kỳ ý tưởng làm thế nào để làm cho nó đệ quy xem các thư mục dưới đây?
Nate Flink

Nếu tôi không quan tâm đến việc thực hiện lệnh thay đổi, đây sẽ là đa nền tảng hay chỉ là unix? Và nó có thực sự là thời gian thực? Một số người theo dõi tập tin ngoài kia có một sự chậm trễ vô lý (phút).
Automatico

2

Bạn có thể đưa lsofvào một watchlệnh và cập nhật nó mỗi <s>giây:

watch -n <s> lsof

và khởi chạy với bất kỳ bộ lọc nào, chẳng hạn như xem pid1, pid2, pid3 và bỏ qua pid4

lsof -p "pid1,pid2,pid3,^pid4"

Nếu điều đó là không đủ, bạn luôn có thể viết các bộ lọc của riêng mình bằng grep.

Đối với OS X, hãy xem câu trả lời của câu hỏi này.


0

entr là tốt đẹp. Bạn có thể lọc các tệp chính xác mà bạn muốn nó xem, như thế này.

find . -name '*.py' | entr python runTests.py

Nếu bạn muốn nó chỉ giám sát một số tệp nhất định trong một thư mục, bạn có thể tạo findlệnh của mình để nó chỉ trả về các tệp bạn muốn xem.

Tôi thấy nó dễ cấu hình hơn fswatch.

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.