Дивіться Filesystem в режимі реального часу на OS X і Ubuntu


11

Я шукаю інструмент CLI, який буде дивитися каталог і виплювати імена файлів, які змінюються в режимі реального часу.

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

Я знаю про inotify( inotify-tools?) І, здається, це те, що мені потрібно, але мені потрібно щось, що сумісне як для Linux (у моєму випадку Ubuntu), так і для OSX.

Це не потрібно блискавично, але потрібно запускати зміни (протягом секунди це розумно). Крім того, мені не обов’язково потрібна точна програма CLI, згадана вище. Якщо існує якась основна технологія, і вона легко написана на обох платформах, це теж було б чудово.


1
Мені подобається fswatchOS X, яку я знайшов у запитанні, позначеному як дублікат - superuser.com/questions/445907/…
cwd

Відповіді:


11

Для цього завдання OS X зазвичай використовує дії " Папка" або " Запуск" .

Єдиний інструмент крос-платформи, про який я знаю, - це сторожовий API для Python (такий доступний для OS X та Linux). Встановити через pip(або easy_install)

pip install watchdog

Він поставляється з інструментом watchmedoкомандного рядка, який дозволяє запускати команди оболонки на системних подіях. Перевірте його загальний синтаксис за допомогоюwatchmedo --help

Ось короткий приклад, де ви можете легко змінити команду та шлях, виділений жирним шрифтом:

watchmedo оболонка-команда \
    --рекурсивний \
    --command = ' echo "$ {watch_src_path}" ' \
     / деякі / папки

Це просто випльовує шляхи до всіх змінених файлів або папок, що дозволяє watchmedoпередавати висновок в іншу команду оболонки.


Схоже, дії папок мають деякі обмеження (і їх важко перевірити без OSX), але watchmedoдля мене це прекрасно працює. Спасибі!
Адріан Шнайдер

2

Я переробив кілька сценаріїв Ruby, які я натрапив, щоб зробити саме те, що ви шукаєте. Ось код 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

Я назвав цей сценарій "OnSaveFolder.rb". Це потребує двох параметрів: папку, за якою ви хочете спостерігати за змінами, і баш-код, який потрібно запустити, коли відбулися зміни. Наприклад,

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

Я сподіваюся, що це допомагає! Я виявив, що рубін працює дуже добре для такого типу речей, і він встановлений на OS X за замовчуванням.


Дав це зйомку, але трохи важко підправити без будь-якого фону Ruby. Все одно, дякую!
Адріан Шнайдер

це чудово. будь-яка ідея, як змусити рекурсивно дивитися папки нижче?
Нейт Флінк

Якщо мені не байдуже виконання команди про зміну, чи це буде багатоплатформа, чи лише unix? І це насправді в реальному часі? У деяких спостерігачів файлів там є смішна затримка (хвилин).
Automatico

2

Ви можете помістити lsofв watchкоманду і це оновлення кожні <s>секунд:

watch -n <s> lsof

і запустіть його будь-яким фільтром, таким як перегляд pid1, pid2, pid3 та ігнорування pid4

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

Якщо цього недостатньо, ви завжди можете писати власні фільтри з грепом.

Для ОС X див. Відповіді на це запитання .


0

entr приємно. Ви можете фільтрувати точні файли, які ви хочете, щоб вони переглядали, як це.

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

Якщо ви хочете, щоб він моніторив лише певні файли всередині каталогу, ви можете скласти свою findкоманду, щоб вона повертала лише ті файли, які ви хочете переглянути.

Мені простіше налаштувати, ніж fswatch.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.