Estoy buscando una herramienta CLI que observe un directorio y muestre los nombres de los archivos que cambian en tiempo real.
some_watch_command /path/to/some/folder | xargs some_callback
Soy consciente de inotify
( inotify-tools
?) y parece ser lo que necesito, pero necesito algo que sea compatible con Linux (en mi caso Ubuntu) y OSX.
No es necesario que sea ultrarrápido, pero sí debe activarse ante los cambios (en un segundo es razonable). Además, no necesito necesariamente el programa CLI exacto mencionado anteriormente. Si existe alguna tecnología subyacente y se puede programar fácilmente en ambas plataformas, también sería fantástico.
Respuesta1
OS X normalmente usaríaAcciones de carpetaoLanzadopara esta tarea.
La única herramienta multiplataforma que conozco es laAPI de vigilanciapara Python (por lo tanto disponible para OS X y Linux). Instálelo a través de pip
(o easy_install
)
pip install watchdog
Viene con la watchmedo
herramienta de línea de comandos, que le permite ejecutar comandos de shell en eventos del sistema. Comprueba su sintaxis general conwatchmedo --help
Aquí hay un breve ejemplo, donde podría modificar fácilmente el comando y la ruta resaltada en negrita:
comando shell watchmedo \ --recursivo \ --comando='eco "${watch_src_path}"'\ /alguna/carpeta
Esto simplemente mostraría las rutas a todos los archivos o carpetas modificados, permitiéndole canalizar watchmedo
la salida de 's a otro comando de shell.
Respuesta2
Modifiqué algunos scripts de Ruby que encontré para hacer exactamente lo que estás buscando. Aquí está el código 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
Llamé a este script "OnSaveFolder.rb". Se necesitan dos parámetros: la carpeta que desea observar en busca de cambios y el código bash que desea ejecutar cuando haya un cambio. Por ejemplo,
ruby OnSaveFolder.rb '/home/Movies' 'echo "A movie has been changed!"'
¡Espero que esto ayude! Descubrí que Ruby funciona muy bien para este tipo de cosas y está instalado en OS X de forma predeterminada.
Respuesta3
Podrías lsof
ingresar un watch
comando y actualizarlo cada <s>
segundos:
watch -n <s> lsof
y ejecútelo con cualquier filtro, como mirar pid1, pid2, pid3 e ignorar pid4
lsof -p "pid1,pid2,pid3,^pid4"
Si eso no es suficiente, siempre puedes escribir tus propios filtros con grep.
Para OS X, vea estopreguntaLas respuestas de
Respuesta4
entrares bueno. Puedes filtrar los archivos exactos que quieres que vea, como este.
find . -name '*.py' | entr python runTests.py
Si desea que solo supervise ciertos archivos dentro de un directorio, puede diseñar su find
comando para que solo devuelva los archivos que desea observar.
Me resulta más fácil de configurar que fswatch
.