Vea el sistema de archivos en tiempo real en OS X y Ubuntu


11

Estoy buscando una herramienta CLI que vea un directorio y escupe 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 tanto con Linux (en mi caso Ubuntu) como con OSX.

No necesita ser rápido como un rayo, pero sí debe activarse ante los cambios (en un segundo es razonable). Además, no necesariamente necesito el programa CLI exacto mencionado anteriormente. Si existe alguna tecnología subyacente y es fácilmente programable en ambas plataformas, eso también sería genial.


1
Me gusta fswatchpara OS X, que encontré en una pregunta etiquetada como duplicado - superuser.com/questions/445907/…
cwd

Respuestas:


11

OS X normalmente usaría Acciones de carpeta o Lanzado para esta tarea.

La única herramienta multiplataforma que conozco es la API de vigilancia para Python (por lo tanto, disponible para OS X y Linux). Instalarlo a través de pip(o easy_install)

pip install watchdog

Viene con la watchmedoherramienta de línea de comandos, que le permite ejecutar comandos de shell en eventos del sistema. Verifique su sintaxis general conwatchmedo --help

Aquí hay un breve ejemplo, donde podría modificar fácilmente el comando y la ruta resaltada en negrita:

watchmedo shell-command \
    --recursivo \
    --command = ' echo "$ {watch_src_path}" ' \
     / some / folder

Esto simplemente escupiría las rutas a todos los archivos o carpetas modificados, permitiéndole canalizar watchmedola salida a otro comando de shell.


Parece que las acciones de carpeta tienen algunas limitaciones (y son difíciles de probar sin OSX), pero watchmedofunciona perfectamente para mí. ¡Gracias!
Adrian Schneider

2

He modificado algunos scripts de Ruby que he encontrado 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 ver para los 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 por defecto.


Le di una oportunidad, pero un poco difícil de ajustar sin ningún fondo de Ruby. ¡Gracias de cualquier manera!
Adrian Schneider

esto es genial. ¿Alguna idea de cómo hacer que recursivamente vea las carpetas a continuación?
Nate Flink

Si no me importa la ejecución del comando en el cambio, ¿sería multiplataforma o solo unix? ¿Y es realmente en tiempo real? Algunos observadores de archivos tienen un retraso ridículo (minutos).
Automático

2

Puede poner lsofun watchcomando y actualizarlo cada <s>segundo:

watch -n <s> lsof

y ejecutar eso 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 las respuestas de esta pregunta .


0

Entr es agradable. Puede filtrar los archivos exactos que desea que vea, de esta manera.

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

Si desea que solo supervise ciertos archivos dentro de un directorio, puede diseñar su findcomando para que solo devuelva los archivos que desea ver.

Me resulta más fácil de configurar que fswatch.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.