GNU/Linux >> Belajar Linux >  >> Linux

Pindahkan file tetapi hanya jika sudah ditutup

Dari lsof halaman manual

Lsof mengembalikan satu (1) jika ada kesalahan yang terdeteksi, termasuk kegagalan menemukan nama perintah, nama file, alamat Internet atau file, nama login, file NFS, PID, PGID, atau UID yang diminta untuk dicantumkan. Jika -Voption ditentukan, lsof akan menunjukkan item pencarian yang gagal dicantumkan.

Jadi itu menunjukkan bahwa lsof failed for some other reason Anda klausa tidak akan pernah dieksekusi.

Sudahkah Anda mencoba memindahkan file sementara proses eksternal Anda masih terbuka? Jika direktori tujuan berada pada sistem file yang sama, maka seharusnya tidak ada masalah dengan melakukannya kecuali jika Anda perlu mengaksesnya di bawah jalur asli dari proses ketiga karena inode yang mendasarinya akan tetap sama. Kalau tidak, saya pikir mv toh akan gagal.

Jika Anda benar-benar harus menunggu hingga proses eksternal Anda selesai dengan file tersebut, Anda lebih baik menggunakan perintah yang memblokir daripada polling berulang kali. Di Linux, Anda dapat menggunakan 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

Perbarui

Seperti yang 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 membuat file terbuka untuk ditulis (contoh kasus mungkin daemon pengindeksan yang ditulis dengan buruk yang membuka file dengan flag baca/tulis padahal seharusnya hanya dibaca saja). inotifywait masih bisa digunakan sebagai pengganti sleep, cukup ganti baris sleep dengan inotifywait -e close /path/to/file .


Sebagai pendekatan alternatif, ini adalah kasus yang sempurna untuk pipa - proses kedua akan memproses keluaran dari proses pertama segera setelah tersedia, daripada menunggu proses penuh selesai:

process1 input_file.dat | process2 > output_file.dat

Keuntungan:

  • Jauh lebih cepat secara umum:
    • Tidak harus menulis dan membaca dari disk (hal ini dapat dihindari jika Anda menggunakan ramdisk).
    • Harus menggunakan sumber daya mesin secara lebih lengkap.
  • Tidak ada file perantara untuk dihapus setelah selesai.
  • Tidak perlu penguncian yang rumit, seperti di OP.

Jika Anda tidak memiliki cara untuk membuat pipa secara langsung tetapi Anda memiliki GNU coreutils Anda dapat menggunakan ini:

tail -F -n +0 input_file.dat | process2 > output_file.dat

Ini akan mulai membaca file input dari awal, tidak peduli seberapa jauh proses pertama adalah melalui penulisan file (meskipun belum dimulai atau sudah selesai).


Linux
  1. Pindahkan file di terminal Linux

  2. Bagaimana Cara Menentukan Proses Yang Membuat File??

  3. Linux – Izin File Hanya Jalankan?

  1. Facl Mengabaikan Izin "x" Tapi Hanya Pada File?

  2. Bagaimana Cara Mengarahkan Hanya Stderr?

  3. Batalkan Penyelesaian, Tapi Hanya Penyelesaian, Di Zsh?

  1. tambahkan baris ke file HANYA jika belum ada dalam file

  2. pindahkan hanya jika file ada dalam skrip shell

  3. Cara menampilkan deskriptor file terbuka tetapi tidak menggunakan perintah lsof