Regarder le système de fichiers en temps réel sur OS X et Ubuntu

Je recherche un outil CLI qui surveillera un répertoire et crache les noms des fichiers qui changent en temps réel.

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

Je suis conscient de l' inotify ( inotify-tools ?) Et il semble être ce dont j'ai besoin, mais j'ai besoin de quelque chose à la fois Linux (dans mon cas Ubuntu) et OSX compatible.

Il n'a pas besoin d'être rapide, mais il faut déclencher des changements (dans une seconde est raisonnable). En outre, je n'ai pas nécessairement besoin du programme CLI exact mentionné ci-dessus. Si une technologie sous-jacente existe et est facilement scriptable sur les deux plateformes, cela serait aussi génial.

OS X utiliserait habituellement Folder Actions ou Launchd pour cette tâche.

Le seul outil multiplate-forme que je connais est l' API de surveillance pour Python (disponible pour OS X et Linux). Installez-le via pip (ou easy_install )

 pip install watchdog 

Il est livré avec l'outil de ligne de commande watchmedo , qui vous permet d'exécuter des commandes shell sur les événements système. Vérifiez sa syntaxe générale avec watchmedo --help

Voici un petit exemple, où vous pouvez facilement modifier la commande et le chemin en surbrillance en gras:

 Watchmedo shell-command \
     --recursive \
     --command = ' echo' $ {watch_src_path} " '\
     / Some / folder

Cela cracherait simplement les chemins d'accès à tous les fichiers ou dossiers modifiés, vous permettant de faire watchmedo la sortie de watchmedo à une autre commande shell.

J'ai modifié certains scripts Ruby que j'ai rencontrés pour faire exactement ce que vous recherchez. Voici le code 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 

J'ai appelé ce script "OnSaveFolder.rb". Il faut deux paramètres: le dossier que vous voulez regarder pour les modifications, et le code bash que vous voulez exécuter lorsqu'il y a eu un changement. Par exemple,

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

J'espère que ça aide! J'ai trouvé que ruby ​​fonctionne très bien pour ce type de chose, et il est installé sur OS X par défaut.

Vous pouvez mettre lsof dans une commande de watch et l'avoir mis à jour chaque <s> secondes:

 watch -n <s> lsof 

Et lancez-le avec n'importe quel filtre, tel que regarder pid1, pid2, pid3 et ignorer pid4

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

Si ce n'est pas suffisant, vous pouvez toujours écrire vos propres filtres avec grep.

Pour OS X, voir les réponses de cette question .

Entr est sympa. Vous pouvez filtrer les fichiers exacts que vous souhaitez regarder, comme ceci.

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

Si vous voulez qu'il ne surveille que certains fichiers à l'intérieur d'un répertoire, vous pouvez créer votre commande de find pour qu'il ne retourne que les fichiers que vous voulez regarder.

Je trouve qu'il est plus facile de configurer que fswatch .