Vim可以破坏文件权限吗?


8

前几天,我像往常一样使用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会以某种方式将文件所有权更改回username:usergroup并保存文件。即使您这样做:

~$ 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-我没有使用任何特殊选项从头开始编译它。


我似乎无法重现该问题,除非采取此处
Davyzhu 2014年

我只是使用问题中的命令再次尝试了它,并且它以相同的方式发生了。我将编辑问题以添加有关我的计算机的详细信息,尽管这似乎可能取决于平台。
zrneely 2014年

我的第一个直觉是,允许您更改具有写访问权的目录中文件的所有权。但似乎并非如此CAP_CHOWN必须致电chown(2)。顺便说一下,我可以在Vim 7.4的Debian上进行复制。
鲍勃

Answers:


10

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

换种方式思考-如果您具有对该目录的读写权限,是什么阻止您复制文件,删除旧文件并以不同的权限重命名新文件?

这正是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 将新文件的权限更改为旧文件的权限-恰好现在有了新所有者。

好,谢谢。我很高兴我知道了这一点。因此,如果我对该目录没有写权限,则将无法使用:w!,这很有意义。
zrneely 2014年

另外,strace信息非常方便-现在,我有了另一个工具供以后进行自己的调查。
zrneely 2014年

1
@zrneely的技巧strace:使用该-o选项将输出写入文件;否则与vim的输出冲突。至于写权限,我没有看到它使用目录权限进行检查,stat但是它确实尝试4913在当前目录中创建一个文件(名为,似乎是随机的),然后将其删除。
鲍勃

似乎4913实际上只是它尝试使用的名字,它的目的检查它是否具有足够的权限。请参阅:bugzilla.redhat.com/show_bug.cgi? id=427711#
Bob
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.