Ich suche nach einem CLI-Tool, das ein Verzeichnis überwacht und die Namen der sich ändernden Dateien in Echtzeit ausgibt.
some_watch_command /path/to/some/folder | xargs some_callback
Ich bin mir inotify
( inotify-tools
?) bewusst und es scheint das zu sein, was ich brauche, aber ich brauche etwas, das sowohl Linux- (in meinem Fall Ubuntu) als auch OSX-kompatibel ist.
Es muss nicht blitzschnell sein, aber es muss bei Änderungen ausgelöst werden (innerhalb einer Sekunde ist angemessen). Außerdem brauche ich nicht unbedingt genau das oben erwähnte CLI-Programm. Wenn eine zugrunde liegende Technologie vorhanden ist und auf beiden Plattformen leicht skriptbar ist, wäre das auch großartig.
Antwort1
OS X verwendet normalerweiseOrdneraktionenoderGestartetfür diese Aufgabe.
Das einzige mir bekannte plattformübergreifende Tool ist dasWatchdog-APIfür Python (daher für OS X und Linux verfügbar). Installieren Sie es über pip
(oder easy_install
)
pip install watchdog
Es wird mit dem watchmedo
Befehlszeilentool geliefert, mit dem Sie Shell-Befehle für Systemereignisse ausführen können. Überprüfen Sie die allgemeine Syntax mitwatchmedo --help
Hier ein kurzes Beispiel, bei dem Sie den Befehl und den fett hervorgehobenen Pfad leicht ändern können:
watchmedo Shell-Befehl \ --rekursiv \ --command='echo "${watch_src_path}"' \ /irgendein/Ordner
Dadurch werden einfach die Pfade zu allen geänderten Dateien oder Ordnern ausgegeben, sodass Sie watchmedo
die Ausgabe an einen anderen Shell-Befehl weiterleiten können.
Antwort2
Ich habe einige Ruby-Skripte, die ich gefunden habe, so optimiert, dass sie genau das tun, was Sie suchen. Hier ist der Ruby-Code:
#!/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
Ich habe dieses Skript „OnSaveFolder.rb“ genannt. Es benötigt zwei Parameter: den Ordner, den Sie auf Änderungen überwachen möchten, und den Bash-Code, den Sie ausführen möchten, wenn eine Änderung vorgenommen wurde. Zum Beispiel:
ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'
Ich hoffe, das hilft! Ich habe festgestellt, dass Ruby für solche Dinge sehr gut funktioniert und standardmäßig auf OS X installiert ist.
Antwort3
Sie können Folgendes lsof
in einen Befehl eingeben und es alle Sekunden watch
aktualisieren lassen :<s>
watch -n <s> lsof
und starten Sie es mit einem beliebigen Filter, z. B. indem Sie pid1, pid2, pid3 beobachten und pid4 ignorieren
lsof -p "pid1,pid2,pid3,^pid4"
Wenn das nicht ausreicht, können Sie mit grep jederzeit Ihre eigenen Filter schreiben.
Für OS X siehe diesFrage's Antworten.
Antwort4
Eintragist nett. Sie können genau die Dateien filtern, die Sie sehen möchten, so wie hier.
find . -name '*.py' | entr python runTests.py
Wenn Sie nur bestimmte Dateien in einem Verzeichnis überwachen möchten, können Sie Ihren find
Befehl so gestalten, dass er nur die Dateien zurückgibt, die Sie überwachen möchten.
Ich finde es einfacher zu konfigurieren als fswatch
.