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

11

Eu estou procurando uma ferramenta CLI que irá assistir a um diretório e cuspir 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 eu preciso, mas preciso de algo que seja tanto Linux (no meu caso Ubuntu) quanto compatível com OSX.

Ele não precisa ser muito rápido, mas precisa ser acionado após 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 existe e é facilmente programável em ambas as plataformas, isso também seria ótimo.

    
por Adrian Schneider 01.06.2012 / 23:58

4 respostas

11

O OS X normalmente usa Ações da pasta ou Launchd para essa tarefa.

A única ferramenta de plataforma cruzada que eu conheço é a API de watchdog para Python (assim disponível para OS X e Linux). Instale-o através de pip (ou easy_install )

pip install watchdog

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

Aqui está um pequeno exemplo, no qual você pode modificar facilmente o comando e o caminho realçados em negrito:

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

Isto simplesmente cuspiria os caminhos para todos os arquivos ou pastas alterados, permitindo que você canalize a saída de watchmedo para outro comando de shell.

    
por 02.06.2012 / 00:07
2

Eu ajustei alguns scripts em Ruby com os quais me deparei 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

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

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

Espero que isso ajude! Descobri que o ruby funciona muito bem para esse tipo de coisa e está instalado no OS X por padrão.

    
por 02.06.2012 / 04:27
2

Você pode colocar lsof em um comando watch e atualizá-lo a cada <s> segundos:

watch -n <s> lsof

e lançar isso 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 o OS X, consulte esta pergunta .

    
por 02.06.2012 / 04:36
0

entr é bom. Você pode filtrar os arquivos exatos que deseja assistir, assim.

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

Se você quiser que ele monitore apenas determinados arquivos dentro de um diretório, você pode criar seu comando find para que ele retorne somente os arquivos que você deseja assistir.

Acho mais fácil configurar do que fswatch .

    
por 14.11.2016 / 23:41