Saya perlu menggunakan proses otomatis (melalui skrip cron 1 menit) yang mencari file tar di direktori tertentu. Jika file tar ditemukan, itu tidak diarsipkan ke lokasi yang sesuai dan kemudian file tar dihapus.
File tar secara otomatis disalin ke server ini melalui SSH dari server lain. Dalam beberapa kasus, file tar sangat besar, dengan banyak file.
Masalah yang saya harapkan terjadi: Jika perlu> 1 menit untuk file tar untuk disalin ke server, dan skrip cron berjalan sekali setiap menit, itu akan melihat file .tar.gz dan mencoba untuk melakukan untar itu, meskipun file tar masih dalam proses untuk menulis.
Apakah ada cara (melalui perintah bash) untuk menguji apakah suatu file saat ini sedang ditulis, atau apakah itu hanya sebagian file, dll?
Salah satu alternatif yang saya pikirkan adalah memiliki file yang akan disalin sebagai ekstensi file yang berbeda (seperti .tar.gz.part
) dan kemudian diganti namanya .tar.gz
setelah transfer selesai. Tapi saya pikir saya akan mencoba mencari tahu apakah ada cara untuk menentukan apakah file tersebut utuh pada baris perintah pertama ... Ada petunjuk?
rsync
menggunakan nama file sementara selama transfer (secara default), dan hanya setelah file sepenuhnya ditransfer, mengganti nama file itu menjadi nama file yang sebenarnya.Jawaban:
Anda berada di jalur yang benar, mengganti nama file adalah operasi atom, jadi melakukan penggantian nama setelah pengunggahan sederhana, elegan, dan tidak rentan kesalahan. Pendekatan lain yang dapat saya pikirkan adalah menggunakan
lsof | grep filename.tar.gz
untuk memeriksa apakah file sedang diakses oleh proses lain.sumber
lsof filename.tar.gz
Lebih efisien dan lebih akurat daripadalsof | grep filename.tar.gz
)Taruhan terbaik Anda adalah menggunakan
lsof
untuk menentukan apakah suatu file telah dibuka oleh proses apa pun:Anda tidak dapat dengan mudah mengetahui apakah itu sedang dalam proses ditulis, tetapi jika sedang ditulis, itu HARUS terbuka.
Sunting: mari kita selesaikan masalah yang sebenarnya di sini daripada mencoba menerapkan solusi yang diusulkan!
Gunakan rsync untuk mentransfer file:
Dengan cara ini, file tidak akan disalin di atas yang sudah ada tetapi disalin ke file sementara (
.big.tar.gz.XXXXXX
) sampai transfer selesai, kemudian dipindahkan ke tempatnya.sumber
Agak tua, tetapi sebagian besar jawaban benar-benar melewatkan inti pertanyaan:
Secara umum, tidak ada. Anda tidak memiliki cukup informasi untuk menentukan hal itu.
Karena menentukan bahwa file ditutup tidak sama dengan menentukan apakah file tersebut utuh . Misalnya, sebuah file akan "ditutup" jika koneksi terputus di tengah jalan saat transfer.
Hanya jawaban Alex yang benar. Dan bahkan dia jatuh cinta untuk menggunakan
lsof
sedikit.Untuk menentukan apakah file telah sepenuhnya, berhasil ditransfer membutuhkan lebih banyak data. Seperti:
Itu cara yang sangat baik untuk berkomunikasi bahwa file telah sepenuhnya dan berhasil ditransfer. Anda juga dapat memindahkan file dari satu direktori ke direktori lain selama Anda tetap berada dalam sistem file yang sama. Atau minta pengirim mengirim
filename.done
file kosong ke sinyal penyelesaian.Tetapi semua metode harus bergantung pada pengirim entah bagaimana menandakan bahwa transfer telah selesai dengan sukses. Karena hanya pengirim yang memiliki informasi itu.
Beberapa format file (seperti PDF) memiliki data di dalamnya yang memungkinkan Anda untuk menentukan apakah file tersebut selesai. Tetapi Anda harus membuka dan membaca hampir seluruh file untuk mengetahuinya.
lsof
hanya akan memberi tahu Anda file tidak lagi terbuka - tidak akan memberi tahu Anda mengapa itu tidak lagi terbuka. Juga tidak akan memberi tahu Anda seberapa besar file yang seharusnya.sumber
Cara terbaik untuk melakukan ini adalah dengan menggunakan incron ("inotify cron system"). Ini memungkinkan Anda untuk menyetel arloji tidak sah di direktori yang kemudian akan memberi tahu Anda tentang operasi file. Dalam hal ini, Anda harus menonton dir untuk close_write. Itu akan memungkinkan Anda untuk kemudian menjalankan perintah Anda setelah file ditutup setelah menulis.
sumber
Sepertinya lsof dapat mendeteksi mode apa file dibuka di bawah:
Lihat di mana dikatakan 1w? Itu berarti bahwa nomor deskriptor file adalah 1 dan mode adalah w, atau tulis.
sumber
FD
lapangan menunjukkan3r
bagi saya ketika file terbuka untuk membaca.Menggunakan
inotifywait
dapat mencapai apa yang Anda cari - ia memiliki kemampuan untuk menunggu sampai file selesai ditulis sebelum menjalankan perintah.Berikut ini akan terus menonton folder untuk file baru dan menjalankan perintah dalam loop ketika menulis ke file telah selesai.
Untuk opsi konfigurasi lainnya, lihat https://linux.die.net/man/1/inotifywatch
sumber