
Ich habe neulich Vim wie üblich verwendet, als mir etwas Merkwürdiges auffiel. Folgendes habe ich getan:
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
Dann habe ich eine Änderung vorgenommen, gespeichert und mit beendet :wq
. Ziemlich normal. Dann jedoch:
~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile
Root sollte also Schreib-/Lesezugriff haben und alle anderen sollten nur Lesezugriff haben. Bearbeiten Sie die Datei, versuchen Sie zu speichern – das geht nicht. Super, funktioniert wie vorgesehen. Wenn Sie jedoch mit speichern :w!
, ändert vim den Dateibesitz irgendwie zurück zu Benutzername:Benutzergruppe und die Datei wird gespeichert. Auch wenn Sie dies tun:
~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile
Du kannstTrotzdemüberschreiben mit :w!
! Was ist los? Wie kann vim die Gesetze zu Dateieigentum und -berechtigungen auf diese Weise verletzen? Ich habe mir die Hilfeseite von vim angesehen :help :w
und Folgendes gefunden:
:w[rite]! [++opt] Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.
Ich konnte bisher nicht in eine Datei in Vim schreiben, obwohl ich das nicht sollte, daher liegt der eigentliche Kern meiner Frage wohl darin, wie ich eine Datei für Vim uneditierbar machen kann und warum dies nicht, wie ich erwarten würde, auf den Dateisystemberechtigungen basiert und welchen Mechanismus Vim zum Bearbeiten der Datei verwendet, den andere Editoren (gedit, nano) nicht verwenden können.
BEARBEITEN: Der Computer, auf dem ich dies ausprobiert habe, verwendet den Linux-Kernel 3.15.5-2-ARCH. Die Versionsnummer von Vim ist 7.4.373-1 und wurde von mir installiert pacman
– ich habe es nicht von Grund auf mit irgendwelchen speziellen Optionen kompiliert.
Antwort1
Ich sehe, dass Ihr aktueller Pfad ~
das Stammverzeichnis Ihres Benutzers ist. Sie sollten Schreibberechtigung für dieses Verzeichnis haben.
Betrachten Sie es anders: Wenn Sie Lese- und Schreibberechtigungen für das Verzeichnis haben, was hindert Sie dann daran, die Datei zu kopieren, die alte zu löschen und die neue mit anderen Berechtigungen umzubenennen?
Dies ist genau, was vim macht!
Wenn Sie vim beispielsweise unter strace ausführen:
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid() = 1000
unlink("testfile") = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10) = 10
fsync(3) = 0
close(3) = 0
chmod("testfile", 0644) = 0
Anhand dieses Protokolls kann ich den folgenden Vorgang erraten:
Einige frühere Berechtigungsprüfungen (und chown
Versuche usw.) werden der Kürze halber weggelassen.
open
Versuch, die Datei zum Schreiben zu öffnen (fehlgeschlagen: Berechtigung verweigert)lstat
Überprüfen Sie den Besitzer der Dateigetuuid
Überprüfen Sie die aktuelle Benutzer-ID, um festzustellen, ob sie mit dem Dateibesitzer übereinstimmt.unlink
Löschen Sie die Datei (dies ist erlaubt, da Schreibberechtigung für das Verzeichnis besteht)open
Erstellen Sie eine neue Datei mit demselben Namenwrite
Der Dateiinhalt (vorher gelesen, ich habe Kauderwelsch eingetippt)fsync
Die Datei auf die Festplatte schreiben (nicht wirklich wichtig)close
chmod
Ändern Sie die Berechtigungen der neuen Datei so, dass sie denen der alten ähneln – sie hat jetzt nur zufällig einen neuen Besitzer.