Apakah pengalihan output ke file menerapkan kunci pada file?

30

Jika saya punya perintah

$ ./script >> file.log

yang dipanggil dua kali, dengan panggilan kedua terjadi sebelum yang pertama berakhir, apa yang terjadi?

Apakah panggilan pertama mendapatkan kunci eksklusif pada file output? Jika demikian, apakah skrip kedua gagal ketika mencoba menulis, atau apakah shell menerima output (memungkinkan skrip untuk mengakhiri) dan melemparkan kesalahan?

Atau apakah file log bisa ditulis dua kali?


sumber
1
Saya tidak tahu sistem apa pun yang akan mengunci file secara default. Apa yang lebih mungkin adalah kedua program akan berakhir dengan interleaving tulisan mereka, karena keduanya akan dalam mode append. Hasilnya akan agak tidak dapat diprediksi. Alih-alih "halo dunia" Anda bisa mendapatkan "hweolrllod".
jw013

Jawaban:

18

Karena Anda menggunakan >>, yang berarti menambahkan, setiap baris output dari setiap instance akan ditambahkan sesuai urutan terjadinya.

Jika keluaran naskah Anda cetak 1\nmelalui 5\ndengan satu detik delay antara masing-masing dan contoh dua dimulai 2,5 detik kemudian Anda akan mendapatkan ini:

1
2
1
3
2
4
3
5
4
5

Jadi untuk menjawab pertanyaan Anda: Tidak.

bahamat
sumber
23

Sistem Unix pada umumnya menghindari kunci wajib. Ada beberapa kasus di mana kernel akan mengunci file terhadap modifikasi oleh program pengguna, tetapi tidak jika itu hanya ditulis oleh program lain. Tidak ada sistem unix yang akan mengunci file karena ada program yang menulisnya.

Jika Anda ingin contoh skrip Anda tidak menginjak jari kaki satu sama lain, Anda perlu menggunakan mekanisme penguncian eksplisit seperti .flock lockfile

Ketika Anda membuka file untuk menambahkan, yang >>tidak, setiap program dijamin untuk selalu menulis ke akhir file. Jadi hasil dari banyak instance tidak akan pernah saling menimpa, dan jika mereka bergantian menulis, output mereka akan berada dalam urutan yang sama dengan yang ditulis.

Hal buruk yang bisa terjadi adalah jika salah satu contoh menulis beberapa potongan output dan mengharapkan mereka untuk keluar bersama. Antara eksekutif menulis dengan satu contoh, contoh lain dapat melakukan tulisan mereka sendiri. Misalnya, jika instance 1 menulis foo, maka instance 2 menulis hellodan hanya kemudian instance 2 menulis bar, maka file tersebut akan berisi foohellobar.

Suatu proses secara efektif menulis ke file ketika memanggil panggilan writesistem. Panggilan ke writeadalah atomik: setiap panggilan untuk writemenulis urutan byte yang tidak akan terganggu oleh program lain. Sering kali ada batasan seberapa banyak data yang writeakan ditulis oleh satu panggilan : untuk ukuran yang lebih besar, hanya permulaan data yang ditulis, dan aplikasi harus menelepon writelagi. Selanjutnya, banyak program melakukan buffering: mereka mengumpulkan data di area memori, lalu menulis data ini dalam satu potongan. Beberapa program membilas buffer output setelah baris lengkap atau pemisahan bermakna lainnya. Dengan program semacam itu, Anda dapat berharap seluruh jalur tidak akan terganggu, asalkan tidak terlalu lama (hingga beberapa kilobyte; ini tergantung pada OS). Jika program tidak menyiram pada titik-titik yang berarti, tetapi hanya berdasarkan pada ukuran buffer, Anda mungkin melihat sesuatu seperti 4kB dari satu contoh, kemudian 4kB dari contoh lain, kemudian lagi 4kB dari contoh pertama dan seterusnya.

Gilles 'SANGAT berhenti menjadi jahat'
sumber