Neden salt okunur bir dosyayı değiştirebilirim?


42

Kısa Soru:

Neden Vim'de salt okunur bir dosyayı yönetici olmadan bile :+ w+ q+ kullanarak değiştirebiliriz !?

Uzun Soru:

Herkes için salt okunur bir metin dosyası (myFile.txt) var:

navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

Yönetici ayrıcalıklarına sahip olmadan Vim ile açabilirim:

navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 

Değiştiriyorum ve: Esc+ :+ w+ q+ tuşlarına basın Enterve şu hata mesajını görüyorum:

E45: 'readonly' option is set (add ! to override)

Şimdiye kadar, her şey mantıklı. Ancak: Esc+ :+ w+ q+ !+ tuşlarına Enterbastığımda, Vim değişiklikleri kaydeder.

Ubuntu 16.04 ve VIM 7.4 kullanıyorum.


1
@Zanna Dosyanın bulunduğu dizine sahip misiniz?
Rob,

Evet, aksi takdirde BÜYÜK bir problem olur :)
Rob

11
Bir dosyayı değiştirmek ve bir dosyayı değiştirmek, farklı izin gereksinimlerine sahip iki farklı şeydir.
David Schwartz

1
Sen de bir göz atmak isteyebilirsiniz bu . Temelde sorunuzu yanıtlar ve @DavidSchwartz'ın doğru bir şekilde işaret ettiği gibi :Modifying a file and replacing a file are two different things
Panagiotis Tabakis

@PanagiotisTabakis Çok güzel bul bu harika .. chmod dosyasını okuyup yazmak ve tekrar sahibi olmak için tekrar yapmak için .. LOVE IT :)
Rob

Yanıtlar:


58

@Rob'ın daha önce de belirtildiği gibi , bunu yalnızca dosyayı içeren dizine yazma erişiminiz varsa yapabilirsiniz. Aynı şeyi, örneğin bir dosyaya yapmaya çalışmak /etcbaşarısızlıkla sonuçlanır.

Bunun nasıl vim yapıldığına gelince dosyayı siler ve yeniden oluşturur. Bunu test etmek için root'a ait bir dosya oluşturdum:

echo foo | sudo tee fff

Daha sonra dosyayı vimtanımladığınız şekilde düzenlemeye devam ettik , ancak straceneler olduğunu görmek için süreci ekleyin:

strace vim fff 2> strace.out

Sonra kontrol ettim strace.outve buldum:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

Böylece dosya önce silindi ( unlink("fff")), sonra aynı isimde yeni bir dosya yaratıldı ( open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)) ve yaptığım değişiklikler ona yazıldı ( write(4, "foasdasdao\n", 11)). Bunu evde denerseniz, düzenledikten sonra vimdosyanın artık size ait olduğunu ve root'a ait olmadığını göreceksiniz.

Yani, kesinlikle konuşmak gerekirse, vimyazma hakkınız olmayan bir dosyayı düzenlemek değildir. Yazma erişiminiz olan bir dizinden bir dosyayı siliyor ve ardından yazma erişimine sahip olduğunuz yeni bir dosya oluşturuyor.



8
@CCJ bu dizinde bir yazma işlemidir, ancak dosyayı değil, hayır. Dosyalara yazma işlemleri, dosyanın içeriğini değiştiren işlemlerdir. Aynı şekilde, dosya oluşturma / silme, içeriğini değiştirdiğinizden beri dizine yazma işlemleridir.
terdon

2
Ayrıca, bu tehlikeli bir işlem sırasıdır. Yerine yeni bir dosya adına yazmak ve daha sonra rename(2)eski dosyayı değiştirmek için kullanmak daha güvenli olacaktır . Öyleyse, verilerinizin diskte olmadığı bir zaman penceresi yoktur.
Peter Cordes

5
@PeterCordes um, Tamam. Bununla birlikte, şikayetlerinizi vim geliştiricilere yönlendirmek isteyebilirsiniz. Bu şeyi kullanmıyorum bile, emac kampındayım.
terdon

3
@ CCJ Bir dosyayı silmek, dosyanın kendisini değil de onu içeren dizine yazma işlemidir. Bir dizinden sorumluysanız (yani, ona yazma erişiminiz varsa), içinde ne olduğunu kontrol edebilmeniz ve tek bir dosyanın sahibinin sizi geçersiz kılmasına izin verilmemesi gerektiği tamamen sezgiseldir.
fkraiem,

16

Üst dizine sahip olduğunuz sürece, dizinin içeriğini değiştirebileceğinizden, izniniz ne olursa olsun, bir dosyayı kaldırabilir veya değiştirebilirsiniz.

Rm gibi başka bir komutla deneyin, size soracaktır, ancak yine de yapabilirsiniz. Dizini yazılabilir yapmayın ve bu onu durdurmalı.

İlave:

Sadece denedim ama dosyaya sahip olduğum sürece, sadece salt okunur olsa bile, dosyayı hala değiştirebiliyorum. Ancak sahipliğini root: root olarak değiştirdiğimde dosyayı yazmak için açamıyor. Böylece root (veya başka birisinin) sahip olduğu değiştirilmiş dosyaları çözer.


7
VIM, yerinde yeniden yazma veya unlink + yeni bir dosya yazma gibi birçok stratejiden birini seçiyor gibi geliyor.
Peter Cordes,

3
@PeterCordes Evet Görünüşe göre söylediklerinizi yapmak için çok çalışacağız :) çok zekice. :)
Rob

16

Kullanarak w!orijinal dosyayı ( yapmanıza izin verilir ) kaldırıyor ve bunun yerine sürümünüzü yazıyorsunuz.

Bir dizine yazma erişiminiz olduğunda, şunları yapabilirsiniz: bu dizindeki dosyaları oluşturabilir, taşıyabilir veya silebilirsiniz.

$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file 
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file

Şimdi kullanıcımı değiştireyim ve dosyayı değiştireyim

$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file

Şimdi orada ne olduğunu görün:

$ cat foo/file
bye

10

Bakınız :help write-readonly:

                                                        write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

Dizine yazma izniniz olduğundan (içindeki dosyaları oluşturabilir, silebilir veya yeniden adlandırabilirsiniz), sistem buna izin verir.


Varsayılan değeri cpoptionsiçermez W:

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global

2

Bu, VIM'in size UNIX'te izinlerin nasıl çalıştığını göz önünde bulundurarak görece önemli olabilecek uyarısıdır. Bunun açık bir şekilde anlaşılamaması, UNIX dosya sistemlerinin dosyanın i-düğümünde depolanan dosya izinlerine sahip olmasıdır. Dizin yapısı bir şekilde ayrıdır ve sadece bu i-düğümleri birbirine bağlar. Dizinler ayrıca, dosyaları bu dosyaya bağlayıp / kaldırabileceğinizi veya okuyabileceğinizi veya alt dizinlere geçip geçmeyeceğinizi söyleyen izinlere sahiptir. Bu tasarım, aynı dosyanın dizin yapısındaki çeşitli yerlerde görünmesini sağlar (sabit bağlantılar yoluyla). "Geçersiz kılmak için ekle" diyerek VIM sizi orijinal dosyanın bağlantısının kaldırılacağı konusunda uyarmaya çalışıyor (bu nedenle dokunulmamış diğer yerlerde kalacaktır) ve yeni dosya oluşturulacak ve dizin yapısındaki orijinal yere bağlanacaktır. Orijinal dosyanın bağlantı sayısının sıfıra düşmesi durumunda, orijinal dosya serbest bırakılır, ancak değilse, dosyayı etkili bir şekilde klonlarsınız. Dosyanın açılması da bağlantı olarak sayılır, bu nedenle eğer bir program dosyayı açtıysa ve "geçersiz kılmak için" ekle! Dosya sadece VIM tarafından dizinden kaldırılır ve dosyayı başka bir programla kapattıktan sonra, başka bir yere bağlanmadıkça dosya serbest bırakılır.

Windows'ta, dosya izinlerinin dizinde depolandığını, bu nedenle Windows izinler paradigması açısından bu vim davranışının gerçekten garip görünebileceğini unutmayın. Dosyaya yazmak için, Windows mantıksal olarak bazı dizin izinlerini, hatta süper dizin izinlerini de kontrol edebilir. Yukarıda da belirtildiği gibi, UNIX'te, dizin izinleri dosyayı listeleyebildiğiniz ve açabildiğiniz kadar manipülasyon için anlamsızdır (yani tüm süper dizinler için x vardı). UNIX'te açılan dosya, açıldıktan sonra tüm dizinlerden bağlantısı kesilmişse artık dosya adına bile sahip olmayabilir.

Örneğin, / home / user1 / foo dosyanız var ve (home hardlinked) / home / user2 / foo ile aynı dosyaya sahip ve dosya hiç kimse tarafından yazılamaz ve P programı tarafından açılmış (okuma-yazma tarafından açılmış) program root tarafından başlatıldı). Eğer kullanıcı1 vim ile açar ve üzerine yazarsa, kendi kopyasını çıkarır ve orijinal dosyayı artık görmez. Daha sonra kullanıcı2 vim ile bağlantısını açar ve içine yazarsa, tekrar bağlantısı kaldırılır ve başka bir kopya oluşturur. P programı orijinal dosyayı görmeye devam eder ve serbestçe okuyabilir veya yazabilir. Program dosyayı kapattıktan hemen sonra dosya kaybolur (dosya sistemi tarafından serbest bırakılır).


2

Hem vim editör süreciniz hem de dosyanız sizin

 getpwnam("navid")->pw_uid

Mülkiyet, böylece de dışarı kabuk olabilir

 :!chmod +w %

ve bir zamanlar bunun daha da basit olduğunu tahmin edebilirsiniz.

 :!rm %

(yalnızca + w gerektiren, ancak bağlantıyı kaldırma izni ve sahiplik bile yok) birinin yazması için çok sık oldu, böylece vim otomatik olarak sunmak ve istek üzerine böyle bir işlemi otomatik olarak gerçekleştirmek üzere yeniden programlandı.

Ablanın üzerine yazmaya çalış

 /home/whoopi/.profile

sadece navid ve bahisler gibi vim'iniz de istediğiniz reddetmenizi sağlar.


Kod düzenleme için bana @Zanna bana hakaret olsa da, biraz acemi biraz itibar rağmen mal olsa, teşekkür ederim.
Roman Czyborra

1

Bu tam olarak bir cevap değil, ancak gerçekten bir dosyayı kimsenin değiştiremeyeceği veya silemeyeceği şekilde ayarlamak istiyorsanız, değiştirilemez hale getirebilirsiniz.

Normalde, bir dosya kök tarafından sahip olsa bile, klasöre yazma izniniz varsa, dosyayı silebilirsiniz. Ancak dosyayı değiştirilemez hale getirdiğinizde, root bile değiştiremez veya silemez.

Bir dosyayı değişmez yapmak için (ihtiyacınız sudo):

sudo chattr +i myFile.txt

Bunu ile görebilirsiniz lsattr(sonuçtaki harf i):

$ lsattr myFile.txt
----i--------e-- myFile.txt

Dosyayı tekrar normal hale getirmek için:

sudo chattr -i myFile.txt

Açıklığa kavuşturmak için: Bir dosya değişmez olduğunda, silinemez, yeniden adlandırılamaz, değiştirilemez ve hatta zor bağlantılı olamaz.

Okumaya değer man chattr, çünkü dosyalar birçok yararlı özelliğe sahip olabilir.

Ayrıca "sınırlı silme" özelliğini de bulabilirsiniz. Bir klasöre yerleştirilirse (bir dosyaya değil), bu, klasörde dosya oluşturan her kimsenin o dosyayı değiştirmesine veya silmesine izin verdiği, ancak kimsenin olmadığı (kök hariç) anlamına gelir. Klasörde /tmpbu bayrak ayarlandı. Bu tbayrakla şunları görebilirsiniz /tmp:

$ ls -l --directory /tmp
drwxrwxrwt 10 root root 4096 Sep  6 09:00 /tmp

Bir klasördeki kısıtlı silme bayrağını ayarlamak veya kaldırmak için:

chmod +t myFolder      # Add the restricted deletion flag.
chmod -t myFolder      # Remove the restricted deletion flag.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.