Apakah bash membuka file di O_APPEND saat menggunakan ">>" di linux?

38

Jika kita gunakan echo 1234 >> some-filemaka Dokumentasi mengatakan bahwa output ditambahkan.

Dugaan saya adalah, jika beberapa file tidak ada, maka O_CREAT akan membuat file baru. Jika >digunakan, maka O_TRUNC akan memotong file yang ada.

Dalam kasus >>: Apakah file akan dibuka sebagai O_WRONLY (atau O_RDWR) dan berusaha untuk mengakhiri dan menulis operasi dilakukan, mensimulasikan O_APPEND? Atau apakah file akan dibuka sebagai O_APPEND, membiarkannya ke kernel untuk memastikan penambahan terjadi?

Saya menanyakan hal ini karena proses conserver menimpa beberapa marker yang dimasukkan oleh echo, ketika file output berasal dari titik mount NFS, & Dokumentasi NFS mengatakan O_APPEND tidak didukung di server, jadi kernel klien harus menanganinya. Saya kira proses conserver menggunakan O_APPEND, tetapi tidak yakin tentang bash >>di linux, maka mengajukan pertanyaan di sini.

Prem
sumber
12
Masalah pada NFS bukanlah yang O_APPENDtidak didukung; masalahnya adalah ini ditiru. Pada sistem file lokal, beberapa proses penulisan ke file yang sama dibuka dengan O_APPEND tidak akan pernah menimpa data masing-masing; pada NFS, O_APPENDditiru dengan mencari sampai akhir sebelum menulis, yang meninggalkan kemungkinan kondisi balapan. Tidak ada jalan lain di NFS ini; setiap penulis paralel perlu menulis file sendiri. Satu-satunya cara untuk mengatasi ini adalah menyiapkan proses server pada server NFS, memiliki logger log |nc server port, dan meminta server menambahkan data yang masuk ke log.
Guntram Blohm mendukung Monica
@GuntramBlohm, +1, terima kasih atas konfirmasinya. Pada dasarnya, saran Anda adalah menggunakan hanya satu proses penulis ke file, dan semua proses penulis lainnya akan melalui proses ini.
Prem
Begitu banyak jawaban bagus, Tidak yakin jawaban mana yang harus saya terima. Bruce Ediger pertama menunjukkan bahwa O_APPEND digunakan. Random832 Selanjutnya menunjukkan bahwa ini diberikan dalam standar. Akhirnya, Eric Renouf menunjukkan kode sumber dengan jawaban yang sama. Ketiga perspektif menambah gambaran lengkap akhir.
Prem
6
Singkatnya, NFS adalah banyak bug dan tidak boleh digunakan.
R ..
2
Ya, tapi kami sudah belajar seperti itu ketika O_EXCL ditemukan.
Kevin

Jawaban:

60

Saya menjalankan ini: strace -o spork.out bash -c "echo 1234 >> some-file"untuk mencari tahu pertanyaan Anda. Inilah yang saya temukan:

open("some-file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

Tidak ada file bernama "some-file" ada di direktori tempat saya menjalankan echoperintah.

Bruce Ediger
sumber
50

Ini tidak hanya dilakukan di Bash, itu diperlukan oleh standar.

Dari Spesifikasi Single Unix :

Redirection output yang ditambahkan akan menyebabkan file yang namanya dihasilkan dari perluasan kata akan dibuka untuk output pada deskriptor file yang ditunjuk. File dibuka seolah-olah fungsi open () sebagaimana didefinisikan dalam volume Antarmuka Sistem POSIX.1-2008 dipanggil dengan flag O_APPEND. Jika file tidak ada, itu harus dibuat.

Oleh karena itu setiap shell yang mematuhi POSIX harus melakukannya. Pada beberapa sistem Unix, /bin/shmungkin shell Bourne non-POSIX (Shell Bourne awalnya ditulis sebelum O_APPENDdiciptakan), dan shell POSIX yang tersedia biasanya ksh, yang akan tersedia shdi lokasi jalur yang berbeda seperti Solaris's /usr/xpg4/bin.

Random832
sumber
2
Menariknya, satu shell yang tidak melakukannya adalah shell Bourne. Shell Bourne terbuka tanpa O_TRUNC dan lseek () hingga akhir. Itu karena itu ditulis sebelum bendera O_APPEND ditambahkan open(). >>sendiri diperkenalkan oleh pendahulunya shell Thomson.
Stéphane Chazelas
1
@ StéphaneChazelas Juga, saya mencari sumber shell C untuk berbagai versi, dan flag O_APPEND tidak diperkenalkan sampai 4.3BSD-Reno.
Random832
Ia mengatakan "seolah-olah", jadi tidak bisakah itu diterapkan secara berbeda (tetapi menghasilkan efek yang dapat diamati yang sama)? Sepertinya standar tidak mengharuskan penggunaan O_APPEND, hanya sesuatu yang berperilaku "seolah-olah".
Thomas
1
@ Thomas Ini berarti Anda akan mendapatkan semua perilaku yang didokumentasikan untuk O_APPEND, yang berarti reposisi pada akhir untuk setiap penulisan. "Seolah-olah" hanyalah bertele-tele standar yang dimaksudkan untuk memungkinkan misalnya dibuka dengan beberapa cara selain benar-benar memanggil fungsi open () pada platform non-tradisional-Unix.
Random832
+1, untuk menunjukkan bahwa perilaku ini ada dalam standar.
Prem
32

Melihat di sumbernya, ia menggunakan O_APPEND. Untuk bash 4.3.30 di make_cmd.cbaris 710-713 baca:

case r_appending_to:                /* >>foo */
case r_append_err_and_out:          /* &>> filename */
  temp->flags = O_APPEND | O_WRONLY | O_CREAT;
  break;
Eric Renouf
sumber
+1, untuk menunjukkan jawaban dari perspektif kode sumber.
Prem
19

Mari selidiki yang menggunakan stracesistem file lokal (non-NFS):

$ strace -eopen -- bash -c "echo foo >> /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

$ strace -eopen -- bash -c "echo foo > /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3

Kerang lainnya, yaitu dash, dash, shdari busybox' dan mkshberperilaku dengan cara yang sama.

Opsi ini -e openberarti -e trace=openhanya melacak open()panggilan sistem.

Franklin Piat
sumber