zrn*_*ely 9 linux vim permissions
前几天我像往常一样使用 Vim,当我注意到一些奇怪的事情时。这是我所做的:
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
Run Code Online (Sandbox Code Playgroud)
然后我进行了更改,并保存并退出: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
Run Code Online (Sandbox Code Playgroud)
所以 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
Run Code Online (Sandbox Code Playgroud)
你仍然可以覆盖: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.
Run Code Online (Sandbox Code Playgroud)
以前我不应该在 vim 中写入文件时,我一直无法写入文件,所以我想我的问题的真正核心是,如何使文件无法被 vim 编辑,为什么它不是基于文件系统权限,就像我期望的那样,以及 vim 使用什么机制来编辑其他编辑器(gedit、nano)无法使用的文件?
编辑:我试过的计算机使用的是 Linux 内核 3.15.5-2-ARCH。Vim 的版本号是 7.4.373-1,它是安装的版本pacman
- 我没有使用任何特殊选项从头编译它。
Bob*_*Bob 10
我可以看到您当前的路径是~
,您的用户的主目录。您应该对该目录具有写权限。
换一种方式想一想 - 如果您对目录具有读写权限,是什么阻止您复制文件、删除旧文件并使用不同权限重命名新文件?
如果你在 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
Run Code Online (Sandbox Code Playgroud)
根据这个日志,我可以猜测出以下过程:
chown
为简洁起见,省略了一些早期的权限检查(和尝试等)。
open
尝试打开文件进行写入(失败:权限被拒绝)lstat
检查文件的所有者getuuid
检查当前用户 ID,查看它们是否与文件所有者匹配unlink
删除文件(这是允许的,因为目录的写权限)open
创建一个同名的新文件write
文件内容(之前读过,我输入了一些胡言乱语)fsync
将文件刷新到磁盘(不是很重要)close
chmod
将新文件的权限更改为旧文件的权限 - 它现在恰好有一个新所有者。