Assista ao sistema de arquivos em tempo real no OS X e Ubuntu

Assista ao sistema de arquivos em tempo real no OS X e Ubuntu

Estou procurando uma ferramenta CLI que observe um diretório e cuspa os nomes dos arquivos que mudam em tempo real.

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

Estou ciente de inotify( inotify-tools?) e parece ser o que preciso, mas preciso de algo que seja compatível com Linux (no meu caso, Ubuntu) e OSX.

Não precisa ser extremamente rápido, mas precisa ser acionado mediante alterações (dentro de um segundo é razoável). Além disso, não preciso necessariamente do programa CLI exato mencionado acima. Se alguma tecnologia subjacente existir e for facilmente programável em ambas as plataformas, isso também seria ótimo.

Responder1

OS X normalmente usariaAções de pastaouLançadopara esta tarefa.

A única ferramenta multiplataforma que conheço é aAPI de vigilânciapara Python (portanto, disponível para OS X e Linux). Instale-o através de pip(ou easy_install)

pip install watchdog

Ele vem com a watchmedoferramenta de linha de comando, que permite executar comandos shell em eventos do sistema. Verifique sua sintaxe geral comwatchmedo --help

Aqui está um pequeno exemplo, onde você poderia facilmente modificar o comando e o caminho destacado em negrito:

comando shell watchmedo \
    --recursivo \
    --comando='eco "${watch_src_path}"'\
    /alguma/pasta

Isso simplesmente exibiria os caminhos para todos os arquivos ou pastas alterados, permitindo canalizar watchmedoa saída de para outro comando do shell.

Responder2

Ajustei alguns scripts Ruby que encontrei para fazer exatamente o que você está procurando. Aqui está o 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

Chamei esse script de "OnSaveFolder.rb". São necessários dois parâmetros: a pasta que você deseja observar em busca de alterações e o código bash que deseja executar quando houver uma alteração. Por exemplo,

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

Eu espero que isso ajude! Descobri que Ruby funciona muito bem para esse tipo de coisa e é instalado no OS X por padrão.

Responder3

Você pode inserir lsofum watchcomando e atualizá-lo a cada <s>segundo:

watch -n <s> lsof

e inicie-o com qualquer filtro, como assistir pid1, pid2, pid3 e ignorar pid4

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

Se isso não for suficiente, você sempre pode escrever seus próprios filtros com o grep.

Para OS X, veja istoperguntaas respostas.

Responder4

entradaé legal. Você pode filtrar os arquivos exatos que deseja assistir, assim.

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

Se você deseja monitorar apenas determinados arquivos dentro de um diretório, você pode criar seu findcomando para que ele retorne apenas os arquivos que você deseja monitorar.

Acho mais fácil configurar do que fswatch.

informação relacionada