OS X obvykle používá Akce složek nebo Spustit pro tento úkol.
Jediný multiplatformní nástroj, který znám, je watchdog API pro Python (tedy dostupné pro OS X a Linux). Nainstalujte jej prostřednictvím pip
(nebo easy_install
)
pip install watchdog
Dodává se s watchmedo
nástroj příkazového řádku, který vám umožňuje spouštět příkazy shellu při systémových událostech. Zkontrolujte jeho obecnou syntaxi pomocí watchmedo --help
Zde je krátký příklad, kde můžete snadno upravit příkaz a cestu zvýrazněnou tučně:
watchmedo shell-command \ --recursive \ --command='echo "${watch_src_path}"' \ /some/folder
To by jednoduše vyplivlo cesty ke všem změněným souborům nebo složkám, což vám umožní propojit watchmedo
's výstup do jiného příkazu shellu.
Vylepšil jsem některé skripty Ruby, na které jsem narazil, aby dělaly přesně to, co hledáte. Zde je kód 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
Tento skript jsem pojmenoval „OnSaveFolder.rb“. Vyžaduje dva parametry:složku, ve které chcete sledovat změny, a kód bash, který chcete spustit, když dojde ke změně. Například,
ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'
Doufám, že to pomůže! Zjistil jsem, že ruby pro tento typ věcí funguje velmi dobře a ve výchozím nastavení je nainstalován v OS X.
Můžete zadat lsof
do watch
a nechte jej aktualizovat každých <s>
sekund:
watch -n <s> lsof
a spusťte to pomocí jakéhokoli filtru, jako je sledování pid1, pid2, pid3 a ignorování pid4
lsof -p "pid1,pid2,pid3,^pid4"
Pokud to nestačí, můžete vždy napsat své vlastní filtry pomocí grep.
Pro OS X viz odpovědi na tuto otázku.