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
.