Quero assistir a uma pasta no meu Mac (Snow Leopard) e executar um script (fornecendo o nome do arquivo que acabou de ser movido para uma pasta (como parâmetro ... x.sh "filename")).
Eu tenho um script todo escrito em bash (x.sh) que moverá alguns arquivos e outras coisas na entrada $ 1. Eu só preciso do OSX para me fornecer o nome do arquivo quando novos arquivos / pastas forem movidos / criados em um diretório.
Algum comando desse tipo?
fswatch
utilitário apresentado como resposta abaixo de fato usa esse método.Respostas:
fswatch
O fswatch é um pequeno programa que usa a API do Mac OS X FSEvents para monitorar um diretório. Quando um evento sobre qualquer alteração nesse diretório é recebido, o comando shell especificado é executado por
/bin/bash
Se você usa o GNU / Linux, o inotifywatch (parte do
inotify-tools
pacote na maioria das distribuições) fornece funcionalidade semelhante.Atualização:
fswatch
agora pode ser usado em várias plataformas, incluindo BSD, Debian e Windows.Sintaxe / Um exemplo simples
A nova maneira de observar vários caminhos - para as versões 1.xe superiores :
A maneira mais antiga para as versões 0.x :
Instalação com Homebrew
A partir de 9/12/13, foi adicionado novamente ao homebrew - yay! Portanto, atualize sua lista de fórmulas (
brew update
) e tudo o que você precisa fazer é:Instalação sem Homebrew
Digite estes comandos em
Terminal.app
Se você não possui um
c
compilador em seu sistema, pode ser necessário instalar as ferramentas de linha de comando Xcode ou Xcode - ambas gratuitas. No entanto, se for esse o caso, você provavelmente deve verificar o homebrew .Opções adicionais para a
fswatch
versão 1.xfonte
make
gera um erro ao não encontrar um makefile. Felizmente, o fswatch agora está no MacPorts, assimsudo port install fswatch
funciona, para aqueles que usam o MacPorts em vez do Homebrew.fswatch ./ | xargs -I{} cp {} ~/Dropbox/backup/latest/
fswatch .
monitorará o diretório atual.fswatch -0 -v -o /path/to/watched/files | xargs -0 -n 1 -I {} [your command]
com-0
para NULLs. Este funciona para mim para menos compilaçãoVocê pode usar o launchd para esse fim. Launchd pode ser configurado para iniciar automaticamente um programa quando um caminho de arquivo é modificado.
Por exemplo, o seguinte launchd config plist iniciará o programa
/usr/bin/logger
quando a pasta da área de trabalho da minha conta de usuário for modificada:Para ativar o config plist, salve-o na pasta LaunchAgents na sua pasta Library como "logger.plist".
No shell, você pode usar o comando
launchctl
para ativar o logger.plist executando:A pasta da área de trabalho agora está sendo monitorada. Sempre que for alterado, você verá uma saída no system.log (use Console.app). Para desativar o logger.plist, execute:
O arquivo de configuração acima usa a
WatchPaths
opção Como alternativa, você também pode usar aQueueDirectories
opção Veja a página de manual do launchd para mais informações.fonte
/usr/bin/logger
com o meu script Bash e removi a"<string>path modified</strong>"
entrada, não consegui encontrar nenhuma maneira de meu script bash saber qual arquivo na minha área de trabalho foi modificado - apenas que o evento ocorreu. Eu tentei olhar para$0
,$1
e só tem o próprio nome do script, notando passado para ele.O vigia do Facebook , disponível via Homebrew, também parece legal. Ele também suporta filtragem:
Observe que o caminho deve ser absoluto.
fonte
Você pode dar uma olhada (e talvez expandir) minha pequena ferramenta
kqwait
. Atualmente, ele fica parado e aguarda um evento de gravação em um único arquivo, mas a arquitetura kqueue permite o empilhamento hierárquico de eventos ...fonte
fswatch
(o que também é bom, já que é um invólucro tão leve que também pode ser modificado para fazer a coisa certa, tenho certeza) onde ele disparava ao executar coisas comogit status
(que na verdade é executado toda vez que o zsh O prompt é renderizado na minha máquina ...) que na verdade meio que estraga esse script elaborado que eu tenho, criando um loop infinito de feedback. O kqwait, no entanto, fornece as informações sobre o arquivo alterado e não é acionadogit status
. Eu preciso que ele seja acionado para gravar.$ brew install kqwait && while true; do kqwait doc/my_file.md; make; done
watchdog é uma API python multiplataforma para monitorar arquivos / diretórios e possui uma ferramenta "truques" embutida que permite disparar ações (incluindo comandos do shell) quando ocorrem eventos (incluindo novo arquivo adicionado, arquivo removido e arquivo alterado).
fonte
Isso é apenas para mencionar entr como uma alternativa no OSX para executar comandos arbitrários quando os arquivos mudam. Acho simples e útil.
fonte
Aqui está uma linha usando
sschober
a ferramenta .fonte
$ brew install kqwait
Editar:
fsw
foi mescladofswatch
. Nesta resposta, qualquer referência afsw
deve agora lerfswatch
.Eu escrevi uma
fswatch
substituição em C ++ chamadafsw
que apresenta várias melhorias:É um projeto do GNU Build System que se baseia em qualquer plataforma suportada (OS X v.> = 10.6) com
Vários caminhos podem ser transmitidos como argumentos diferentes:
Ele despeja um registro detalhado com todas as informações do evento, como:
Sua saída é fácil de analisar, para que a
fsw
saída possa ser canalizada para outro processo.-l, --latency
.-n, --numeric
.strftime
cadeias de formato com-t, --time-format
.-u, --utc-time
.Obtendo fsw:
fsw
está hospedado no GitHub e pode ser obtido clonando seu repositório:Instalando o fsw:
fsw
pode ser instalado usando os seguintes comandos:Outras informações:
Também escrevi um post introdutório no blog, onde você pode encontrar alguns exemplos sobre como
fsw
funciona.fonte
As ações de pasta do Apple OSX permitem automatizar tarefas com base nas ações executadas em uma pasta.
fonte
Minha bifurcação do fswatch fornece a funcionalidade de saída
inotifywait -m
um pouco menos (sem espera, mais! Eu tenho muito mais problemas no Linux cominotifywait
...) saída compatível com análise.É uma melhoria em relação ao original
fswatch
porque envia o caminho real do arquivo alterado por STDOUT, em vez de exigir que você forneça um programa que ele bifurca.Tem sido sólido como base de uma série de scripts bash assustadores que eu uso para automatizar coisas.
(isso é fora de tópico)
inotifywait
no Linux, por outro lado, exige muitos elogios e ainda não descobri uma boa maneira de gerenciá-lo, embora eu ache que algo baseadonode.js
possa ser o bilhete.fonte
brew install https://raw.github.com/mlevin2/homebrew/116b43eaef08d89054c2f43579113b37b4a2abd3/Library/Formula/fswatch.rb
Eu tenho um GIST para isso e o uso é bastante simples
Para ilustrar, o seguinte comando ecoará
Hello World
sempre quefile1
OUfile2
mudar; e a verificação do intervalo padrão é de 1 segundoSe eu quiser verificar a cada 5 segundos, posso usar a
-t
bandeira-v
ativa overbose
modo que mostra informações de depuração-q
fazwatchfiles
executar silenciosamente (#
será mostrado para que o usuário possa ver o programa em execução)-qq
fazwatchfiles
executar completamente silenciosamente-h
mostra a ajuda e o usohttps://gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55
fonte
Acabei fazendo isso no macOS. Tenho certeza de que isso é terrível de várias maneiras:
fonte
Se você deseja usar o NodeJS, pode usar um pacote chamado chokidar (ou chokidar-cli, na verdade) para assistir e, em seguida, usar
rsync
(incluído no Mac):Comando Rsync:
$ rsync -avz --exclude 'some-file' --exclude 'some-dir' './' '/my/destination'
Chokidar cli (instalado globalmente via npm):
chokidar \"**/*\" -c \"your-rsync-command-above\"
fonte
Aqui está uma alternativa simples de linha única para usuários que não têm o
watch
comando que desejam executar um comando a cada 3 segundos:while :; do your-command; sleep 3; done
É um loop infinito que é basicamente o mesmo que fazer o seguinte:
watch -n3 your-command
fonte
your-command
a E / S do disco é uma leitura / gravação garantida do disco a cada 3 segundos - ou 10.800 vezes a cada hora. Usando eventos do sistema de arquivos que você seria garantido que I / O (e outras operações caros) só acontecem quando você altera um arquivo (que geralmente é apenas um par de vezes por hora.)watch
coisas por períodos temporários para ver o que algo está fazendo. Não uso minha técnica mencionada para aplicativos de produção ou algo assim. Por exemplo, eu gostaria de ver o progresso dedd
, e minha técnica faz isso acontecer (substituindoyour-command
conforme apropriado para enviar o sinal apropriadodd
).