Beobachten Sie das Dateisystem in Echtzeit unter OS X und Ubuntu

Beobachten Sie das Dateisystem in Echtzeit unter OS X und Ubuntu

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 watchmedoBefehlszeilentool 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 watchmedodie 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 lsofin einen Befehl eingeben und es alle Sekunden watchaktualisieren 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 findBefehl so gestalten, dass er nur die Dateien zurückgibt, die Sie überwachen möchten.

Ich finde es einfacher zu konfigurieren als fswatch.

verwandte Informationen