Não há uma maneira portátil de fazer isso. Você pode tentar fuser
, lsof
, inotify
, FAM
e outros.
Eu preciso escrever um script Unix Shell Script tran.sh que mova os arquivos de entrada csv da pasta / exp / files para o diretório / exp / ready.
Os arquivos de entrada csv são gravados na pasta /exp/files
por um servidor FTP cujo comportamento não posso mudar trivialmente. Em tran.sh
shell script eu preciso garantir antes de fazer um movimento do arquivo de entrada csv do diretório / exp / files e nenhum outro processo está gravando no arquivo.
Como posso fazer isso?
Não há uma maneira portátil de fazer isso. Você pode tentar fuser
, lsof
, inotify
, FAM
e outros.
Tente usar fuser [FILE]
. Ele retornará diferente de zero se o arquivo não estiver em uso.
Veja alguns exemplos de código que aguardarão a conclusão de um arquivo:
#!/bin/sh
FROMDIR='/exp/files'
DESTDIR='/exp/ready'
function move_file_if_ready () {
if [ -f "$1" ]; then
while fuser "$1" 2>/dev/null 1>&2 ; do
sleep 1
done
mv "$1" "$DESTDIR"
fi
}
for "$fn" in "$FROMDIR"/*.csv; do
move_file_if_ready "$fn"
done
você pode usar o lsof
r=$(lsof /exp/files )
if [ ! -z "$r" ] ;then
mv /exp/files/*csv /exp/ready
fi
A maneira certa de fazer isso é fazer com que o processo de gravação dos arquivos seja renomeado ou movido por vontade própria quando feito com a gravação. Qualquer outra coisa é propensa a condições de corrida e / ou problemas de permissão.
Alguns exemplos específicos de casos problemáticos:
Outras condições de corrida mais sutis também podem existir - e, independentemente disso, o lsof, o fusor e outros não são ferramentas POSIX e não estão disponíveis em todos os lugares.
Exigir, como uma questão do protocolo, que os processos que os gravam os movam para o local final ao serem completados; é a única abordagem segura e portátil.
EDIT: Foi esclarecido que os arquivos estão sendo escritos não por um processo arbitrário (que pode fechar e reabri-los), mas por um servidor FTP. Nesse caso, o incron pode ser usado para executar um script arbitrário sempre que um arquivo for fechado nesse diretório.
Eu não acho que você possa fazer isso sem modificar processos que criam esses arquivos. Sempre que temos uma tarefa como essa em nossos sistemas, garantimos que o processo que cria o arquivo torne-o executável no final. Assim, o processo que move ou processa de alguma outra maneira esses arquivos podem verificar o bit executável para garantir que o processo de origem tenha terminado de trabalhar com um arquivo.
Tags unix