J'utilisais Vim l'autre jour comme d'habitude, quand j'ai remarqué quelque chose d'étrange. Voici ce que j'ai fait:
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
Ensuite, j'ai fait un changement, j'ai enregistré et j'ai quitté avec :wq
. Assez normal. Mais alors:
~$ 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
Donc, root devrait avoir un accès r / w et tout le monde devrait avoir seulement lu. Modifiez le fichier, essayez de l'enregistrer - vous ne pouvez pas. Génial, fonctionne comme prévu. Cependant, si vous enregistrez avec :w!
, vim change en quelque sorte la propriété du fichier en nom d'utilisateur: groupe d'utilisateurs et le fichier est enregistré. Même si vous faites cela:
~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile
Vous pouvez toujours écraser avec :w!
! Qu'est-ce qui se passe? Comment vim peut-il enfreindre les lois sur la propriété et l'autorisation des fichiers comme celle-ci? J'ai regardé la page d'aide dans vim en disant :help :w
et j'ai trouvé ceci:
: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.
Je n'ai pas pu écrire dans un fichier dans vim auparavant alors que je ne devrais pas le faire, donc je suppose que le véritable cœur de ma question est de savoir comment rendre un fichier non éditable par vim et pourquoi n'est-il pas basé sur un fichier les autorisations système, comme je m'y attendais, et quel mécanisme vim utilise-t-il pour éditer le fichier que les autres éditeurs (gedit, nano) ne peuvent pas utiliser?
EDIT: L'ordinateur sur lequel j'ai essayé utilise le noyau Linux 3.15.5-2-ARCH. Le numéro de version de Vim est 7.4.373-1, et c'est celui installé par pacman
- je ne l'ai pas compilé à partir de zéro avec des options spéciales.
CAP_CHOWN
est nécessaire d'appeler chown(2)
. Soit dit en passant, je peux reproduire sur Debian, avec vim 7.4.