我们经常看到我们在编辑后尝试在 vim 中保存的文件被报告为只读。解决这个问题的方法是添加!wq
,我试图弄清楚内部是什么允许 vim 程序获得足够的权限来写入只读文件?
是否有内部标志被切换或 vim 暂时获得了一段时间的特权?
Kus*_*nda 26
当您w!
在 Vim 中进行操作时,实际发生的情况取决于谁拥有该文件。
如果您(当前用户)是文件的所有者,Vim 将在重写文件之前将权限更改为可写。然后它删除写权限以将权限位恢复到从一开始的状态。
如果您不是该文件的所有者,但如果您在当前目录中有写权限,Vim 将删除原始文件并将该文档写入一个同名的新文件中。新文件将被分配与原始文件相同的权限,但归您所有。
Vim 永远不会获得能够写入文件的提升权限。
上述机制是任何需要写入只读文件的程序都必须选择的可用选项(即在写入文件时临时更改权限,或删除文件并创建一个新文件),以及Vim 最终选择做什么可能取决于许多可配置的设置。
正如在下面的评论中看到的那样,上述内容存在一些混淆。如果您想亲眼看看在您的特定品牌的 Unix 上设置 Vim 时实际发生了什么,我建议您跟踪 Vim 在写入只读文件时所做的系统调用。这是如何完成的取决于您使用的是什么 Unix。在 Linux 上,这可能是通过例如strace vim file
(然后编辑文件,保存w!
并退出)来完成的。
这是第一种情况(从OpenBSD 上的ktrace
+输出kdump
):
13228 vim CALL chmod(0x19b1d94b4b10,0100644<S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH|S_IFREG>)
13228 vim NAMI "file"
13228 vim RET chmod 0
13228 vim CALL lseek(3,0x1000,SEEK_SET)
13228 vim RET lseek 4096/0x1000
13228 vim CALL write(3,0x19b1e0aa9000,0x1000)
Run Code Online (Sandbox Code Playgroud)
这会更改文件的权限,使其可写(与 一起S_IWUSR
使用的标志chmod()
)并将缓冲区写入其中。
然后设置原始权限:
13228 vim CALL fchmod(4,0100444<S_IRUSR|S_IRGRP|S_IROTH|S_IFREG>)
13228 vim RET fchmod 0
13228 vim CALL close(4)
13228 vim RET close 0
Run Code Online (Sandbox Code Playgroud)
对于另一种情况:
它首先取消链接(删除)文件,然后重新创建它(在写入文件并稍后更改权限之前):
44487 vim CALL unlink(0x79fdbc1f000)
44487 vim NAMI "file"
44487 vim RET unlink 0
44487 vim CALL open(0x79fdbc1f000,0x201<O_WRONLY|O_CREAT>,0644<S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH>)
44487 vim NAMI "file"
44487 vim RET open 4
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6473 次 |
最近记录: |