Vim 可以破坏文件权限吗?

Vim 可以破坏文件权限吗?

前几天我像往常一样使用 Vim,突然发现有些奇怪。以下是我所做的:

~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile

然后我做了一个更改,保存并退出:wq。很正常。但是,然后:

~$ 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 应该具有 r/w 访问权限,而其他所有人应该只有读取权限。编辑文件,尝试保存 - 您不能。太棒了,按预期工作。但是,如果您使用 保存:w!,vim 会以某种方式将文件所有权更改回用户名:用户组,并且文件被保存。即使您这样做:

~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile

你可以仍然用 覆盖:w!!发生了什么?vim 怎么能这样破坏文件所有权和权限的规律?我查看了 vim 的帮助页面,:help :w发现了以下内容:

: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.

以前我无法在 vim 中写入文件,所以我想我的问题的真正核心是,如何让文件无法被 vim 编辑,以及为什么它不像我期望的那样基于文件系统权限,以及 vim 使用什么机制来编辑其他编辑器(gedit、nano)无法使用的文件?

编辑:我尝试使用的计算机使用的是 Linux 内核 3.15.5-2-ARCH。Vim 的版本号是 7.4.373-1,它是安装的pacman- 我没有使用任何特殊选项从头编译它。

答案1

我可以看到您当前的路径是~,即您的用户主目录。您应该对该目录具有写权限。

换个角度想想——如果您对该目录具有读写权限,那么是什么阻止您复制文件、删除旧文件并使用不同的权限重命名新文件呢?

这正是 vim 所做的!


如果你在 strace 下运行 vim,例如:

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

根据这个日志,我可以猜测以下过程:

chown为了简洁起见,省略了一些早期的权限检查(和尝试等)。

  1. open尝试打开文件进行写入(失败:权限被拒绝)
  2. lstat检查文件的所有者
  3. getuuid检查当前用户 ID,看其是否与文件所有者匹配
  4. unlink删除文件(这是允许的,因为目录具有写权限)
  5. open创建同名的新文件
  6. write文件内容(请先阅读,我输入了一些乱码)
  7. fsync将文件刷新到磁盘(不太重要)
  8. close
  9. chmod将新文件的权限更改为与旧文件类似 - 它现在恰好有新的所有者。

相关内容