Dari lsof
halaman manual
Lsof mengembalikan satu (1) jika kesalahan terdeteksi, termasuk kegagalan untuk menemukan nama perintah, nama file, alamat Internet atau file, nama login, file NFS, PID, PGID, atau UID yang diminta untuk didaftar. Jika opsi -V ditentukan, lsof akan menunjukkan item pencarian yang gagal tercantum.
Jadi itu akan menyarankan bahwa lsof failed for some other reason
klausa Anda tidak akan pernah dieksekusi.
Sudahkah Anda mencoba hanya memindahkan file sementara proses eksternal Anda masih terbuka? Jika direktori tujuan berada pada sistem file yang sama, maka seharusnya tidak ada masalah dengan melakukan itu kecuali Anda perlu mengaksesnya di jalur asli dari proses ketiga karena inode yang mendasarinya akan tetap sama. Kalau tidak, saya pikir mv
akan gagal pula.
Jika Anda benar-benar harus menunggu sampai proses eksternal Anda selesai dengan file tersebut, Anda lebih baik menggunakan perintah yang memblokir daripada melakukan polling berulang kali. Di Linux, Anda dapat menggunakannya inotifywait
untuk ini. Misalnya:
inotifywait -e close_write /path/to/file
Jika Anda harus menggunakan lsof
(mungkin untuk portabilitas), Anda dapat mencoba sesuatu seperti:
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
Memperbarui
Seperti dicatat oleh @JohnWHSmith di bawah ini, desain teraman akan selalu menggunakan lsof
loop seperti di atas karena ada kemungkinan bahwa lebih dari satu proses akan membuka file untuk ditulis (contoh kasus mungkin adalah daemon pengindeksan yang ditulis dengan buruk yang membuka file dengan membaca / tulis flag padahal seharusnya hanya dibaca). inotifywait
masih bisa digunakan daripada tidur, ganti saja garis tidur dengan inotifywait -e close /path/to/file
.