Quero mover um arquivo grande criado por um processo externo assim que for fechado.
Este comando de teste está correto?
if lsof "/file/name"
then
# file is open, don't touch it!
else
if [ 1 -eq $? ]
then
# file is closed
mv /file/name /other/file/name
else
# lsof failed for some other reason
fi
fi
EDIT: o arquivo representa um conjunto de dados e eu tenho que esperar até que esteja completo para movê-lo para que outro programa possa atuar nele. É por isso que preciso saber se o processo externo é feito com o arquivo.
linux
shell-script
monitoring
open-files
lsof
Peter Kovac
fonte
fonte
lsof
nada, só preciso verificar se a extensão do arquivo não é.tmp
. Isso o torna trivial. No entanto, eu estou feliz que eu pedi a minha pergunta desde que eu aprendi um pouco sobrelsof
einotify
e outras coisas.Respostas:
Na
lsof
página do manualPortanto, isso sugere que sua
lsof failed for some other reason
cláusula nunca será executada.Você já tentou mover o arquivo enquanto o processo externo ainda o abre? Se o diretório de destino estiver no mesmo sistema de arquivos, não haverá problemas em fazer isso, a menos que você precise acessá-lo no caminho original a partir de um terceiro processo, pois o inode subjacente permanecerá o mesmo. Caso contrário, acho
mv
que falhará de qualquer maneira.Se você realmente precisar esperar até que seu processo externo seja concluído com o arquivo, é melhor usar um comando que bloqueie, em vez de pesquisar repetidamente. No Linux, você pode usar
inotifywait
para isso. Por exemplo:Se você deve usar
lsof
(talvez para portabilidade), tente algo como:Atualizar
Conforme observado por @JohnWHSmith abaixo, o design mais seguro sempre usaria um
lsof
loop como acima, pois é possível que mais de um processo tenha o arquivo aberto para gravação (um exemplo de caso pode ser um daemon de indexação mal escrito que abre arquivos com a leitura / write flag quando realmente deve ser somente leitura).inotifywait
ainda pode ser usado em vez de dormir, basta substituir a linha de sono porinotifywait -e close /path/to/file
.fonte
inotify
. Infelizmente, ele não está instalado na minha caixa, mas tenho certeza que vou encontrar um pacote em algum lugar. Veja minha edição por um motivo pelo qual eu preciso que o arquivo seja fechado: é um conjunto de dados e deve ser concluído antes de processá-lo.inotifywait
impedir que o script faça "polling" duas vezes, o OP ainda precisa fazer check-lsof
in em um loop: se o arquivo for aberto duas vezes, o fechamento de uma vez poderá acionar oinotify
evento, mesmo que o arquivo não esteja pronto para ser manipulado (por exemplo, no seu último trecho de código, suasleep
chamada pode ser substituída porinotifywait
).close_write
deve estar ok, pois apenas um processo pode ter o arquivo aberto para gravação por vez. Ele pressupõe que outro não o abra logo após ser fechado, mas o mesmo problema existe com alsof
pesquisa.CLOSE_WRITE
é acionado duas vezes).Como uma abordagem alternativa, esse é o caso perfeito para um canal - o segundo processo processará a saída do primeiro processo assim que estiver disponível, em vez de aguardar a conclusão do processo completo:
Vantagens:
Se você não tem como criar um canal diretamente, mas possui o GNU coreutils, pode usar isso:
Isso começará a ler o arquivo de entrada desde o início, não importa a que distância o primeiro processo seja gravado (mesmo que ainda não tenha sido iniciado ou já esteja concluído).
fonte
cat
eprocess2
poderia terminar antes deprocess1
terminar. Eles não bloqueariam.