Desde la lsof
página del manual
Lsof devuelve uno (1) si se detectó algún error, incluida la imposibilidad de localizar nombres de comandos, nombres de archivos, direcciones de Internet o archivos, nombres de inicio de sesión, archivos NFS, PID, PGID o UID que se le pidió que enumerara. Si se especifica la opción -V, lsof indicará los elementos de búsqueda que no pudo enumerar.
Eso sugeriría que su lsof failed for some other reason
cláusula nunca se ejecutaría.
¿Has intentado mover el archivo mientras tu proceso externo todavía lo tiene abierto? Si el directorio de destino está en el mismo sistema de archivos, entonces no debería haber problemas para hacerlo a menos que necesite acceder a él bajo la ruta original desde un tercer proceso ya que el inodo subyacente seguirá siendo el mismo. De lo contrario, creo mv
que fallará de todos modos.
Si realmente necesita esperar hasta que su proceso externo termine con el archivo, es mejor usar un comando que bloquee en lugar de sondear repetidamente. En Linux, puede usar inotifywait
para esto. P.ej:
inotifywait -e close_write /path/to/file
Si debe usar lsof
(tal vez para portabilidad), podría intentar 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
Actualizar
Como señaló @JohnWHSmith a continuación, el diseño más seguro siempre usaría un lsof
bucle como el anterior, ya que es posible que más de un proceso tenga el archivo abierto para escribir (un caso de ejemplo puede ser un demonio de indexación mal escrito que abre archivos con la lectura / escribir bandera cuando realmente debería ser de solo lectura). inotifywait
sin embargo, todavía se puede usar en lugar de dormir, solo reemplace la línea de sueño con inotifywait -e close /path/to/file
.