Dalla lsof
pagina man
Lsof restituisce uno (1) se viene rilevato un errore, incluso l'incapacità di individuare nomi di comandi, nomi di file, indirizzi o file Internet, nomi di accesso, file NFS, PID, PGID o UID che è stato richiesto di elencare. Se viene specificata l'opzione -V, lsof indicherà gli elementi di ricerca che non è stato elencato.
Questo suggerirebbe che la tua lsof failed for some other reason
clausola non sarebbe mai stata eseguita.
Hai provato a spostare il file mentre il tuo processo esterno è ancora aperto? Se la directory di destinazione si trova sullo stesso filesystem, non dovrebbero esserci problemi a farlo a meno che non sia necessario accedervi dal percorso originale da un terzo processo poiché l'inode sottostante rimarrà lo stesso. Altrimenti penso mv
che fallirà comunque.
Se hai davvero bisogno di aspettare fino al termine del processo esterno con il file, è meglio usare un comando che blocca invece di eseguire ripetutamente il polling. Su Linux, puoi usarlo inotifywait
per questo. Per esempio:
inotifywait -e close_write /path/to/file
Se devi usare lsof
(forse per la portabilità), potresti provare qualcosa del tipo:
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
Aggiornare
Come notato da @JohnWHSmith di seguito, il progetto più sicuro userebbe sempre un lsof
ciclo come sopra poiché è possibile che più di un processo abbia il file aperto per la scrittura (un caso di esempio potrebbe essere un demone di indicizzazione mal scritto che apre i file con la lettura / scrivi flag quando dovrebbe davvero essere di sola lettura). inotifywait
può comunque essere usato al posto del sonno, basta sostituire la linea del sonno con inotifywait -e close /path/to/file
.