Saya ingin memindahkan file besar yang dibuat oleh proses eksternal segera setelah ditutup.
Apakah perintah tes ini benar?
if lsof "/file/name"
then
# file is open, don't touch it!
else
if [ 1 -eq $? ]
then
# file is closed
mv /file/name /other/file/name
else
# lsof failed for some other reason
fi
fi
EDIT: file tersebut merupakan dataset dan saya harus menunggu sampai selesai untuk memindahkannya sehingga program lain dapat menindaklanjutinya. Itu sebabnya saya perlu tahu apakah proses eksternal dilakukan dengan file.
linux
shell-script
monitoring
open-files
lsof
Peter Kovac
sumber
sumber
lsof
sama sekali, saya hanya perlu memeriksa apakah ekstensi file tidak.tmp
. Itu membuatnya sepele. Namun saya senang saya mengajukan pertanyaan saya karena saya belajar sedikit tentanglsof
daninotify
dan sebagainya.Jawaban:
Dari
lsof
halaman manualJadi 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:Jika Anda harus menggunakan
lsof
(mungkin untuk portabilitas), Anda dapat mencoba sesuatu seperti: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 denganinotifywait -e close /path/to/file
.sumber
inotify
. Sayangnya, itu tidak diinstal pada kotak saya tetapi saya yakin saya akan menemukan paket di suatu tempat. Lihat hasil edit saya untuk alasan mengapa saya perlu file ditutup: ini adalah dataset dan harus lengkap sebelum diproses lebih lanjut.inotifywait
akan mencegah skrip dari "polling" dua sering, OP masih perlu memeriksalsof
dalam satu lingkaran: jika file dibuka dua kali, menutup sekali dapat memicuinotify
acara, meskipun file tidak siap untuk menjadi dimanipulasi (misalnya, dalam cuplikan kode terakhir Anda,sleep
panggilan Anda dapat diganti denganinotifywait
).close_write
harus ok karena hanya satu proses yang dapat membuat file terbuka untuk ditulis sekaligus. Itu mengasumsikan bahwa yang lain tidak akan membukanya langsung setelah ditutup, tetapi kemudian masalah yang sama muncul denganlsof
polling.CLOSE_WRITE
dipicu dua kali).Sebagai pendekatan alternatif, ini adalah kasus yang sempurna untuk pipa - proses kedua akan memproses output dari proses pertama segera setelah tersedia, daripada menunggu proses lengkap untuk selesai:
Keuntungan:
Jika Anda tidak memiliki cara untuk membuat pipa secara langsung tetapi Anda memiliki GNU coreutils, Anda dapat menggunakan ini:
Ini akan mulai membaca file input dari awal, tidak peduli seberapa jauh proses pertama melalui penulisan file (bahkan jika itu belum dimulai atau sudah selesai).
sumber
cat
danprocess2
bisa selesai sebelumprocess1
selesai. Mereka tidak akan memblokir.