Jika ada proses terus menulis ke file, dan saya ingin mengambil kendali file dengan root, saya bisa melakukan sesuatu seperti ini:
sudo rm somefile; sudo touch somefile
Apakah mungkin untuk proses penambahan untuk menambahkan file di antara kedua perintah ini? Jika demikian, adakah cara untuk memastikan bahwa tidak ada perintah lain yang dijalankan di antaranya?
Jawaban:
Baris perintah dirantai pada dasarnya adalah skrip shell kecil; itu akan menjalankan perintah pertama menggunakan prosedur fork + exec yang biasa, tunggu sampai keluar, kemudian jalankan perintah kedua dengan cara yang sama. Di antara kedua perintah tersebut, ada beberapa waktu arbitrer yang digunakan oleh shell dalam pembukuan dan pemrosesan, di mana multiprocessing biasa terjadi dan proses-proses lain yang sewenang-wenang dapat melakukan hal-hal lain yang sewenang-wenang. Jadi jawabannya adalah 'tidak'. (Jika Anda benar-benar melakukan ini, Anda akan menemukan bahwa entri direktori untuk
somefile
menghilang, tetapi file itu sendiri tetap (karena dibuka oleh suatu proses) sampai ditutup. Ruang disk yang digunakan oleh file tidak akan direklamasi sampai itu terjadi. Sementara itu ,touch
perintah akan membuat file baru yang tidak terkait dengan nama dan jalur yang sama.)Jika Anda ingin mengubah kepemilikan file menjadi root, lakukan saja
sudo chown root:root somefile
(meskipun saya tidak yakin bagaimana itu akan mempengaruhi proses dengan filehandhandle terbuka untuk itu). Jika Anda ingin menghancurkan konten file saat ini, cobatruncate -s 0 somefile
(proses yang berjalan akan terus menambahkan file yang sekarang kosong). Jika itu hal lain, mungkin perjelas apa yang ingin Anda lakukan.sumber
chown
ing somefile tidak akan memengaruhi proses yang memiliki pegangan file ke somefile.exec 3>somefile; sudo chmod 0600 somefile; echo hello world >&3; sudo cat somefile; exec 3>&-
.Tidak.
rm
Perintah yang diikuti olehtouch
perintah sama sekali bukan atom. Ini akan menjadi waktu yang lama antara dua perintah - mungkin dalam kisaran milidetik. Banyak yang bisa terjadi selama waktu itu. Jika Anda kurang beruntung, kredensial sudo Anda bahkan mungkin kedaluwarsa.Satu program yang memanggil
unlink
danopen
memanggil akan meninggalkan jendela yang jauh lebih pendek untuk balapan, tetapi itu masih bisa terjadi.Pendekatan yang lebih aman adalah membuat file baru dengan nama sementara dan menggunakan
rename
panggilan sistem. "Menimpa" nama denganrename
panggilan sistem dijamin bersifat atomik. Ini dapat dicapai dengan menggunakantouch
danmv
.Tetapi suatu proses yang telah membuka file lama untuk menulis dapat terus menulis lama setelah itu telah dihapus. Ini akan menjadi kasus untuk file yang dihapus menggunakan
unlink
dan yang dihapus menggunakanrename
.sumber
Setelah suatu proses memiliki filehandle terbuka untuk dibaca, tidak masalah apa yang Anda lakukan dengan kepemilikan atau izin: proses tersebut dapat terus mengakses file. Anda bahkan dapat menghapus file dan prosesnya akan dapat terus mengaksesnya melalui filehandle.
Pertimbangkan izin untuk menjadi gerbang kontrol untuk mendapatkan filehandle.
Jika Anda ingin membuat file secara atom, daripada melakukan ini:
Anda dapat mempertimbangkan ini:
yang secara atom akan diganti
somefile
dengananotherfile
. (Saya lebih suka menggunakanmv -f
tetapi saya tidak dapat menemukan pernyataan yang menjamin ini panggilanrename(2)
sistem panggilan.Mungkin Anda dapat memperbarui Pertanyaan Anda untuk menjelaskan apa yang Anda maksud dengan "mengendalikan file". Anda mungkin memiliki Masalah XY di sini.
sumber
mv -f
untuk mendapatkanrename(2)
panggilan sistem. Anda benarln
tidak akan melakukannya, karena selalu menggunakanlink(2)
system call, yang tidak bisa diganti secara atom.ln -f
lakukan sajaunlink(2)
pada target pertama.ln
di otak. Saya tidak yakin bagaimana mendapatkanrename(2)
jaminan untuk terlibat dan sudah terlambat untuk menggali lebih jauhmv
"akan melakukan tindakan yang setara dengan"rename(old, new)
. pubs.opengroup.org/onlinepubs/9699919799/utilities/mv.html .mv -f
bertindak sepertimv -i
jika tujuan tidak dapat ditulisi, tetapi tidak seperticp -f
atau diln -f
mana ia akan memutuskan tautan terlebih dahulu.Tidak tapi
sudo rm somefile; sudo touch somefile
aman di sebagian besar situasi.
Sebagian besar proses membuka file dan kemudian menggunakan deskriptor file yang diperoleh untuk mengakses konten file.
Jika suatu proses membuka file tertentu, dalam sh:
Kemudian proses lain bebas untuk membatalkan tautan (= menghapus) file seseorang dan file yang diarsipkan di mana file dibuka oleh proses pertama (3 dalam kasus ini) akan terus merujuk ke konten asli file somefile, yang sekarang menjadi file dalam limbo.
akan membuat file baru yang tidak terkait dan semua proses yang lama dibuka lama dan sekarang hanya menggunakan file yang diarsipkan untuk merujuknya tidak akan terpengaruh karena mereka merujuk ke file yang berbeda - file yang sekarang dalam limbo.
Jika proses non-root berusaha untuk merujuk ke file tertentu dengan nama, mereka akan mendapatkan kesalahan EPERM, karena file baru milik root.
Jika Anda ingin mencegah beberapa proses di bawah pengguna yang sama (misalnya, root) dari merusak file, linux memiliki penguncian file wajib dan penasihat. Anda dapat menggunakan
flock
perintah dalam skrip shell untuk mengunci file advisory (lihat halaman manual untuk info lebih lanjut).sumber