Bagaimana "cp" menangani file yang terbuka?

15

Saya memiliki dua direktori terpisah. Pengguna memuat file ke dalam file pertama. Ada tugas cronjob di latar belakang yang menyalin file setiap 5 menit ke direktori kedua.

Apa yang terjadi jika pengguna belum menyelesaikan unggahannya dan cronjob menyalin file? Perhatikan bahwa dua direktori dimiliki oleh pengguna yang berbeda, cronjob dilakukan sebagai root.

Pengap
sumber
silakan baca posting ini untuk melihat apa yang terjadi dalam kasus seperti ini: unix.stackexchange.com/questions/49299/…
Serge
Terima kasih, postingan bagus yang Anda tulis. Tapi pertanyaan saya lebih terkait cp, bukan untuk penanganan file linux secara umum. Saya pikir mungkin cp memeriksa apakah file tersebut masih terbuka dan menunggu sampai ditutup atau sesuatu.
Tersumbat
Tidak. Tidak cpakan menunggu sampai file diunggah sepenuhnya. Seperti yang kami perkirakan kecepatan transfer jaringan lebih rendah daripada hanya menyalin file dari satu lokasi ke lokasi lain di dalam host yang sama, maka pada titik tertentu cpakan mencapai akhir file saat ini dan akan berhenti menyalin. Solusi untuk masalah Anda dapat dengan sederhana: pertama pengguna mengunggah file dengan beberapa nama file yang rusak (misalnya diawali dengan .(karakter dot) .Ketika transfer dilakukan pengguna mengubah nama menjadi nama asli. Kemudian pekerjaan cron hanya terlihat untuk file yang tidak dimulai dengan.
Serge

Jawaban:

17

cptidak tahu tentang file yang dibuka. Jadi, jika pengguna pertama mengunggah file besar dan cronjob (atau proses lainnya) mulai menyalin file ini, itu hanya akan menyalin sebanyak yang sudah ditulis. Anda dapat memikirkan hal ini dengan cara ini - cpmembuat salinan dari apa yang saat ini ada di disk, tidak masalah jika file tersebut selesai. Jika tidak, Anda tidak dapat menyalin file log misalnya.

Krzysztof Adamski
sumber
Terima kasih, itu yang ingin saya ketahui! Apakah ada cara sederhana untuk menghindarinya? Saya memeriksa halaman manual cp tetapi tidak menemukan manfaat.
Pengap
Untuk melakukan apa sebenarnya? Untuk menyalin semua file kecuali yang terbuka? Saya tidak berpikir ada cara mudah untuk melakukan ini (selain menulis skrip Anda sendiri yang menggunakan fuser+ cp. Salinan seperti itu akan sangat tidak dapat diandalkan. Ini tidak akan menyalin file yang dibuka di editor teks misalnya.
Krzysztof Adamski
@Stuffy, mungkin di cronjob Anda, Anda bisa daftar file yang terbuka dengan lsof? Output dari itu dimaksudkan agar mudah diproses. Anda dapat memfilter file yang sedang dibuka (misalnya, oleh cp) untuk menulis.
Wojtek Rzepala
@WojtekRzepala, saya akan melihat ini, terima kasih. Mungkin saya akan menulis skrip kecil yang dijalankan oleh cronjob
Stuffy
@Stuffy: Perlu diingat bahwa itu mungkin tidak benar-benar dapat diandalkan jika tidak dijalankan oleh pengguna root (masalah yang sama dengan fusertentu saja) karena alat ini mungkin tidak menampilkan semua file.
Krzysztof Adamski
7

cptidak tahu program apa yang mungkin membuat file terbuka. Tidak ada keajaiban di dalamnya cp. Desain unix sengaja menghindari meletakkan segala jenis kunci pada file kecuali ada alasan kuat (meyakinkan bahwa kernel membutuhkannya). Pada topik ini, lihat Apakah mengarahkan output ke file menerapkan kunci pada file?

Situasi seperti itu, di mana file diproduksi oleh produsen dan, setelah selesai, dikonsumsi oleh konsumen, adalah hal biasa. Cara biasa untuk menangani ini adalah membuat produser menulis file sementara yang tidak akan dicari konsumen, kemudian setelah produser selesai memindahkan file ke tempat di mana konsumen akan menemukannya. Memindahkan file (pada sistem file yang sama) adalah operasi atom: pada titik tertentu, bagi konsumen, file berubah dari tidak ada di sana menjadi ada di sana.

Jadi atur pekerjaan unggahan Anda untuk memindahkan file ke direktori lain ketika selesai melakukan unggahan. Arahkan pekerjaan cron di direktori yang berbeda ini.

Gilles 'SO- berhenti menjadi jahat'
sumber
6

Sepertinya Anda ingin melakukan pekerjaan dir sync.

Karena opsi -u, --update daricp

salin hanya ketika file SOURCE lebih baru dari file tujuan atau ketika file tujuan hilang

Jadi, Anda dapat menambahkan cronjob seperti cp -auv SOURCEDIR/* DESTDIRyang akan menyalin file-file yang waktu modifikasinya telah berubah. Itu berartiDESTDIR pada akhirnya akan mendapatkan salinan lengkap saat pengunggahan selesai.

rsyncdapat melakukan pekerjaan yang sama. misalnya,rsync -av SOURCEDIR/ DESTDIR ,.

Meskipun opsi -a diterapkan, beberapa atribut tertentu (misalnya, kepemilikan) hanya dapat dipertahankan oleh pengguna-super.

Lihat man cp, man rsyncuntuk detailnya.

Edw4rd
sumber
Berhati-hatilah untuk mengandalkan entri terbaru di folder tujuan --- mereka mungkin bukan file yang lengkap.
dubiousjim