Melakukan operasi penulisan atom dalam file dalam bash

13

Setelah melalui dokumentasi bash , pertanyaan ini dan yang ini masih belum jelas bagi saya bagaimana saya bisa melakukan operasi penulisan atom (tambahkan) ke file dalam bash. Saya memiliki skrip yang dijalankan dalam beberapa kasus dan pada beberapa titik harus menulis data ke file:

echo "$RESULT" >> `pwd`/$TEMP_DIR/$OUT_FILE

Bagaimana mungkin membuat semua operasi penulisan dari semua skrip yang berjalan bersamaan ke file atomic (sehingga data dari satu instance tidak tumpang tindih data dari yang lain)?

Sebi
sumber
1
FYI Anda tidak perlu `pwd`; Anda bisa menggunakan titik ( .). Anda juga harus mengutip seluruh nama file karena menyertakan variabel .
Wildcard
1
Anda mungkin juga ingin melihat kemungkinan menggunakan FIFO .
Wildcard
@ Kartu Ucapan Terima kasih. Saya menggunakan pwdskrip sebelumnya untuk memberi tahu pengguna tentang direktori kerja saat ini dan juga menulis entri dalam file log. melihat-lihat FIFO sekarang.
Sebi
1
Sebenarnya ada pengantar yang lebih baik untuk FIFO di situs ini; tautan yang saya berikan beberapa menit yang lalu adalah spesifikasi POSIX untuk mkfifodan bukan tingkat pengantar yang sebenarnya.
Wildcard
Baik itu FIFO atau file, Anda masih menghadapi risiko bahwa dua instance menulis pada saat yang sama dan memutarbalikkan output masing-masing.
clacke

Jawaban:

10

Tampaknya Anda perlu menggunakan flockseperti pada contoh dari man ( http://linux.die.net/man/1/flock )

(
flock -x 200

# Put here your commands that must do some writes atomically

) 200>/var/lock/mylockfile 

Dan letakkan semua perintah Anda yang harus berupa atom di ().


sumber
Operasi tulis akan menjadi atom meskipun (kawanan -s 200 # Letakkan di sini perintah Anda yang harus melakukan beberapa menulis secara atom) 200> / var / lock / mylockfile disebar di beberapa skrip yang menjalankan secara bersamaan? Atau, sebaliknya, apakah kunci tersebut relatif terhadap / var / lock / mylockfile?
Sebi
1
Skrip Anda mengunci / var / lock / mylockfile, tetapi hanya satu contoh skrip Anda yang bisa mendapatkan kunci tulis. Contoh lain akan menunggu sampai /var/lock/mylockfiletersedia untuk mengunci.
-s adalah kunci bersama - cocok untuk dibaca, untuk kunci tulis Anda harus menggunakan -x / -e. Itu ada di halaman manual yang Anda tautkan.
Evan Benn
Pada titik manakah pembukaan kunci terjadi dalam kode ini? Begitu ada sesuatu yang ditulis /var/lock/mylockfileoleh proses yang disebut flock -x?
Chris Stryczynski
@ChrisStryczynski Anda dapat menjalankan contoh ini (flock -x 200; date; sleep 10; date;) 200>/var/lock/mylockfiledalam dua shell dan melihat bahwa membuka kunci hanya terjadi setelah semua perintah di () dieksekusi (yang dalam subkulit)
4

flockadalah salah satu cara operasi yang saling terkait. Utilitas adalah bagian dari tool util-linux dan hanya tersedia untuk Linux. Utilitas lain, tersedia di berbagai platform yang lebih luas, didasarkan pada setlockutilitas Daniel J. Bernstein dari paket daemontools:

Alat-alat ini beroperasi dengan paradigma yang sedikit berbeda dengan yang digunakan dalam jawaban M. Kurenkov (salah satunya) flock juga dapat digunakan, tetapi tidak dalam jawaban itu). Satu memanggil setlockprogram untuk memuat rantai ke perintah yang harus saling bertautan. setlockitu sendiri membuka dan mengunci file kunci, dan meninggalkan deskriptor file untuk itu terbuka dalam prosesnya. Kunci tetap ada selama proses itu berlangsung (kecuali perintah berikutnya dirantai untuk secara eksplisit melepaskan kunci dengan menemukan dan menutup deskriptor file terbuka).

Untuk kasus dalam pertanyaan, seseorang harus mengaitkan perintah yang menghasilkan garis keluaran, dengan menyadari bahwa ini memanggil sebuah eksternal echo sebagai pengganti shell bawaanecho :

setlock mylockfile echo "$ RESULT" >> ./$TEMP_DIR/$OUT_FILE

Dalam hal ini tidak perlu saling mengunci membuka file output dalam mode append. Jika ya, seseorang harus membuka file itu di dalam kunci, yang mengharuskan baik menggunakan program sepertifdredir / redirfd:

setlock mylockfile fdredir --append 1 "./$TEMP_DIR/$OUT_FILE" echo "$ HASIL"
yang mana dapat berubah menjadi fungsi shell jika diinginkan:

outfile () {setlock mylockfile fdredir --append 1 "./$TEMP_DIR/$OUT_FILE" "$ @"; }
[...]
outfile echo "$ HASIL"
atau bertahan dengan sintaks shell dan menafsirkannya dengan shell kedua yang berjalan di bawah interlock, memerlukan beberapa kutipan non-sepele jika variabel shell seseorang tidak diekspor sebagai variabel lingkungan:

setlock mylockfile sh -c 'echo' "$ HASIL" '>> >> ./'$TEMP_DIR'/'$OUT_FILE' "'

Ini tentu saja menggeneralisasi hal-hal selain menulis ke file output:

setlock mylockfile sh -c '... saling bertautan; barang ... '

JdeBP
sumber