Guarda il filesystem in tempo reale su OS X e Ubuntu


11

Sto cercando uno strumento CLI che guardi una directory e sputi i nomi dei file che cambiano in tempo reale.

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

Sono a conoscenza di inotify( inotify-tools?) E sembra essere quello di cui ho bisogno, ma ho bisogno di qualcosa che sia Linux (nel mio caso Ubuntu) e compatibile con OSX.

Non ha bisogno di essere velocissimo, ma deve innescarsi in caso di cambiamenti (entro un secondo è ragionevole). Inoltre, non ho necessariamente bisogno dell'esatto programma CLI di cui sopra. Se esiste una tecnologia di base ed è facilmente gestibile tramite script su entrambe le piattaforme, sarebbe fantastico.


1
Mi piace fswatchper OS X che ho trovato su una domanda che è stata contrassegnata come duplicata - superuser.com/questions/445907/…
cwd,

Risposte:


11

OS X userebbe in genere Azioni cartella o Launchd per questa attività.

L'unico strumento multipiattaforma che conosco è l' API watchdog per Python (quindi disponibile per OS X e Linux). Installalo tramite pip(o easy_install)

pip install watchdog

Viene fornito con lo watchmedostrumento da riga di comando, che consente di eseguire comandi shell su eventi di sistema. Controlla la sua sintassi generale conwatchmedo --help

Ecco un breve esempio, in cui è possibile modificare facilmente il comando e il percorso evidenziato in grassetto:

watchmedo shell-command \
    --ricorsivo \
    --command = ' echo "$ {watch_src_path}" ' \
     / some / cartella

Ciò sputerebbe semplicemente i percorsi di tutti i file o cartelle modificati, consentendo di reindirizzare watchmedol'output a un altro comando shell.


Sembra che le azioni delle cartelle abbiano alcune limitazioni (e sono difficili da testare senza OSX), ma watchmedofunziona perfettamente per me. Grazie!
Adrian Schneider,

2

Ho modificato alcuni script di Ruby che ho trovato per fare esattamente quello che stai cercando. Ecco il codice 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

Ho chiamato questo script "OnSaveFolder.rb". Sono necessari due parametri: la cartella che si desidera controllare per le modifiche e il codice bash che si desidera eseguire in caso di modifica. Per esempio,

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

Spero che questo possa essere d'aiuto! Ho scoperto che ruby ​​funziona molto bene per questo tipo di cose ed è installato su OS X per impostazione predefinita.


Ci ho dato un colpo, ma un po 'difficile da modificare senza alcun background di Ruby. Grazie comunque!
Adrian Schneider,

è fantastico qualche idea su come farlo guardare ricorsivamente le cartelle qui sotto?
Nate Flink,

Se non mi interessa l'esecuzione del comando in caso di modifica, sarebbe multipiattaforma o solo unix? Ed è davvero in tempo reale? Alcuni osservatori di file là fuori hanno un ritardo ridicolo (minuti).
Automatico,

2

Puoi inserire lsofun watchcomando e farlo aggiornare ogni <s>secondo:

watch -n <s> lsof

e avvialo con qualunque filtro, come guardare pid1, pid2, pid3 e ignorare pid4

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

Se ciò non bastasse, puoi sempre scrivere i tuoi filtri con grep.

Per OS X, vedi le risposte a questa domanda .


0

entr è simpatico. Puoi filtrare i file esatti che vuoi che guardino, in questo modo.

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

Se vuoi che controlli solo determinati file all'interno di una directory, puoi creare il tuo findcomando in modo che restituisca solo i file che vuoi guardare.

Trovo più facile da configurare di fswatch.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.