技术解析

请教,为什么 vim 的强制保存这么厉害?
0
2021-06-16 16:32:19
idczone

无意中发现的一个问题,在 centos7 和 debian 系统上都出现了,应该不是发行版的问题。 先在普通用户主目录下创建一个文件 f1:touch f1 查看其属性:

ls -l

-rw-r--r-- 1 vk vk  26 10 月 13 11:37 f1

然后修改文件 f1 的所有者和所属组:

sudo chown root:root f1

ls -l

-rw-r--r-- 1 root root   0 10 月 13 11:36 f1

在 vk 用户下编辑:vim f1 写入一些内容之后,直接 :w是无法保存的,提示不能写入只读文件。但可以用:w!保存,保存后所有者和所属组就回到了 用户 vk 和 组 vk 。

(但在其他目录下就不行了)

vim 的强制保存这么厉害吗?还是 Linux 对主目录有什么特殊设置?


: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' flag
to 'cpoptions' to avoid this.

我以前也不知道,不过我在 mac 下试了下。 换了个思路,在 chown 到 root 之后,不带 sudo 直接 chown 回来是不行的,但我可以删除它,相对于其他自己名下的文件,只是多了个是否确定而已。
那么,vim 自然可以进行,先删除后重新创建并写入的操作(当然可能有更好的解决方案,我只是描述了这并不是只有 vim 可以实现)

vim 应该是删了这个文件重新写了一个。这个文件普通用户是可以删掉的。

想要证明的话应该有很多办法,比如 ls -li 看文件的实体 node 号是否发生了变化

删除权限应该是来自于用户对自己的主目录的操作权限,而不是对这个文件的操作权限。用户对自己的主目录有完全控制权,那么对其下的文件也就可以删除,这是文件权限不能决定的。

vim 就利用这个权限删除再重新创建不就好了?

我用 stat 命令查看了 inode 号,没有发生变化

确实是删除之后重新创建了: https://github.com/neovim/neovim/blob/master/src/nvim/fileio.c`stat` 命令查看时,文件的创建时间也发生了改变

我刚才试了一下,时间确实变了。但我又创建了一个文件,没有改变所有者等属性,保存后,它的时间也变了,而且是三个时间都变了。也就是说,不管是不是强制保存,文件的三个时间属性都会发生改变

> 但我又创建了一个文件,没有改变所有者等属性,保存后,它的时间也变了,而且是三个时间都变了。
我试了下结果不是这样,创建时间 没有变欸

这是修改所有者之后强制保存的,所有的时间都变了
```
[email&rm f1 f2
[email&touch f1
[email&stat f1
文件:f1
大小:0 块:0 IO 块:4096 普通空文件
设备:804h/2052d Inode:171 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 1000/ vk) Gid:( 1000/ vk)
最近访问:2020-10-16 16:28:49.059459602 +0800
最近更改:2020-10-16 16:28:49.059459602 +0800
最近改动:2020-10-16 16:28:49.059459602 +0800
创建时间:2020-10-16 16:28:49.059459602 +0800
[email&sudo chown root:root f1
[sudo] vk 的密码:
[email&stat f1
文件:f1
大小:0 块:0 IO 块:4096 普通空文件
设备:804h/2052d Inode:171 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2020-10-16 16:28:49.059459602 +0800
最近更改:2020-10-16 16:28:49.059459602 +0800
最近改动:2020-10-16 16:29:08.523425651 +0800
创建时间:2020-10-16 16:28:49.059459602 +0800
[email&vim f1
[email&stat f1
文件:f1
大小:11 块:8 IO 块:4096 普通文件
设备:804h/2052d Inode:171 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 1000/ vk) Gid:( 1000/ vk)
最近访问:2020-10-16 16:29:48.343175347 +0800
最近更改:2020-10-16 16:29:48.343175347 +0800
最近改动:2020-10-16 16:29:48.343175347 +0800
创建时间:2020-10-16 16:29:48.343175347 +0800
```
这是没有修改所有者的情况:
```
[email&touch f2
[email&stat f2
文件:f2
大小:0 块:0 IO 块:4096 普通空文件
设备:804h/2052d Inode:2063 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 1000/ vk) Gid:( 1000/ vk)
最近访问:2020-10-16 16:31:13.618070299 +0800
最近更改:2020-10-16 16:31:13.618070299 +0800
最近改动:2020-10-16 16:31:13.618070299 +0800
创建时间:2020-10-16 16:31:13.618070299 +0800
[email&vim f2
[email&stat f2
文件:f2
大小:9 块:8 IO 块:4096 普通文件
设备:804h/2052d Inode:2082 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 1000/ vk) Gid:( 1000/ vk)
最近访问:2020-10-16 16:31:31.381773198 +0800
最近更改:2020-10-16 16:31:31.381773198 +0800
最近改动:2020-10-16 16:31:31.385773129 +0800
创建时间:2020-10-16 16:31:31.381773198 +0800
```
所有的时间都变了。
此外,用 stat 命令查看时,在 CentOS7 中显示的是三种时间,没有创建时间。但在 debian testing 中显示四种时间,包括创建时间。应该是新版系统后加的吧

我遇到有时候 w!也是不行的,必须要 sudo 打开 vim

我觉得 Vim 的强制保存还不够,所以单独写了条按键映射
noremap :w !sudo tee %:e!:x

这就不清楚了,好奇怪

这个情况目前只在一种情况下发现了:在用户编辑在自己的主目录下编辑所有者不是自己的那些文件。其他情况我还没怎么试过

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服