Solusi 1:
Taruhan terbaik Anda adalah menggunakan lsof
untuk menentukan apakah file telah dibuka oleh proses apa pun:
# lsof -f -- /var/log/syslog
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1520 syslog 1w REG 252,2 72692 16719 /var/log/syslog
Anda tidak dapat dengan mudah mengetahui apakah itu sedang dalam proses penulisan, tetapi jika sedang ditulis, itu HARUS terbuka.
Sunting:mari selesaikan masalah yang sebenarnya di sini daripada mencoba menerapkan solusi yang diusulkan!
Gunakan rsync untuk mentransfer file:
○ → rsync -e ssh remote:big.tar.gz .
Dengan cara ini, file tidak akan disalin di atas yang sudah ada tetapi disalin ke file sementara (.big.tar.gz.XXXXXX
) hingga transfer selesai, lalu dipindahkan ke tempatnya.
Solusi 2:
Anda berada di jalur yang benar, mengganti nama file adalah operasi atom, jadi melakukan penggantian nama setelah mengunggah itu sederhana, elegan, dan tidak rawan kesalahan. Pendekatan lain yang dapat saya pikirkan adalah menggunakan lsof | grep filename.tar.gz
untuk memeriksa apakah file sedang diakses oleh proses lain.
Solusi 3:
Agak kuno, tetapi sebagian besar jawaban benar-benar melenceng dari pertanyaan:
Tapi saya pikir saya akan mencoba mencari tahu apakah ada cara sederhana untuk menentukan apakah file tersebut utuh di baris perintah terlebih dahulu...
Secara umum, tidak ada. Anda tidak memiliki cukup informasi untuk menentukannya.
Karena menentukan bahwa file tersebut ditutup tidak sama dengan menentukan apakah file tersebut utuh . Misalnya, file akan "ditutup" jika koneksi terputus di tengah proses transfer.
Hanya jawaban @ Alex yang benar. Dan bahkan dia jatuh karena menggunakan lsof
agak.
Untuk menentukan apakah file sudah lengkap, berhasil ditransfer membutuhkan lebih banyak data. Seperti:
Salah satu alternatif yang saya pikirkan adalah membuat file disalin sebagai ekstensi file yang berbeda (seperti
.tar.gz.part
) lalu diganti namanya menjadi.tar.gz
setelah transfer selesai.
Itu cara yang sangat bagus untuk mengomunikasikan 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 mengirimkan filename.done
kosong file untuk penyelesaian sinyal.
Tetapi semua metode harus bergantung pada pengirim yang entah bagaimana menandakan bahwa transfer telah berhasil diselesaikan. Karena hanya pengirim yang memiliki informasi tersebut.
Beberapa format file (seperti PDF) memiliki data di dalamnya yang memungkinkan Anda untuk menentukan apakah file tersebut lengkap. Tetapi Anda harus membuka dan membaca hampir seluruh file untuk mengetahuinya.
lsof
hanya akan memberi tahu Anda bahwa 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.
Solusi 4:
Cara terbaik untuk melakukan ini adalah dengan menggunakan incron ("sistem inotify cron"). Ini memungkinkan Anda untuk mengatur jam tangan inotify pada direktori yang kemudian akan memberi tahu Anda tentang operasi file. Dalam hal ini, Anda harus memperhatikan dir untuk close_write. Itu akan memungkinkan Anda untuk kemudian menjalankan perintah Anda setelah file ditutup setelah penulisan.
Solusi 5:
Sepertinya lsof dapat mendeteksi mode apa yang dibuka file:
lsof -f -- a_file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 52391 bob 1w REG 1,2 15 19545007 a_file
Lihat di mana dikatakan 1w? Itu berarti nomor deskriptor file adalah 1 dan modenya adalah w, atau tulis.