OS X in genere utilizza 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 il watchmedo
strumento da riga di comando, che consente di eseguire comandi della shell sugli eventi di sistema. Controlla la sua sintassi generale con watchmedo --help
Ecco un breve esempio, in cui puoi facilmente modificare il comando e il percorso evidenziato in grassetto:
watchmedo shell-command \ --recursive \ --command='echo "${watch_src_path}"' \ /some/folder
Questo sputerebbe semplicemente i percorsi di tutti i file o le cartelle modificati, permettendoti di reindirizzare watchmedo
l'output di un altro comando di shell.
Ho ottimizzato 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". Prende due parametri:la cartella che vuoi controllare per le modifiche e il codice bash che vuoi eseguire quando c'è stata una modifica. Ad esempio,
ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'
Spero che questo aiuti! Ho scoperto che Ruby funziona molto bene per questo tipo di cose ed è installato su OS X per impostazione predefinita.
Potresti inserire lsof
in un watch
comando e fallo aggiornare ogni <s>
secondi:
watch -n <s> lsof
e avvialo con qualsiasi filtro, ad esempio guardando pid1, pid2, pid3 e ignorando 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.