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.


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.


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.


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;

+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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.