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 watchmedo
ferramenta 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 watchmedo
a 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 lsof
um watch
comando 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 find
comando para que ele retorne apenas os arquivos que você deseja monitorar.
Acho mais fácil configurar do que fswatch
.