Na lsof
página do manual
Lsof retorna 1 (um) se algum erro foi detectado, incluindo a falha em localizar nomes de comando, nomes de arquivos, endereços ou arquivos da Internet, nomes de login, arquivos NFS, PIDs, PGIDs ou UIDs que foram solicitados a listar. Se a opção -V for especificada, lsof indicará os itens de pesquisa que não foram listados.
Portanto, 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:
inotifywait -e close_write /path/to/file
Se você deve usar lsof
(talvez para portabilidade), tente algo como:
until err_str=$(lsof /path/to/file 2>&1 >/dev/null); do
if [ -n "$err_str" ]; then
# lsof printed an error string, file may or may not be open
echo "lsof: $err_str" >&2
# tricky to decide what to do here, you may want to retry a number of times,
# but for this example just break
break
fi
# lsof returned 1 but didn't print an error string, assume the file is open
sleep 1
done
if [ -z "$err_str" ]; then
# file has been closed, move it
mv /path/to/file /destination/path
fi
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 por inotifywait -e close /path/to/file
.