Na lsofpá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 reasonclá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 mvque 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 inotifywaitpara 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 lsofloop 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). inotifywaitainda pode ser usado em vez de dormir, basta substituir a linha de sono por inotifywait -e close /path/to/file.