当前位置: 首页>>技术问答>>正文


为什么我可以修改read-only文件?

, , , , ,

问题描述

简短问题:

为什么我们可以使用: + w + q + !操作Vim中的read-only文件,即使不是管理员?

长问题:

我有一个文本文件(myFile.txt),每个人都是read-only:

navid@navid-ThinkPad-T530:~/ubuntuTest$ ls -l myFile.txt 
-r--r--r-- 1 navid navid 26 Aug 22 21:21 myFile.txt

我可以在没有管理员权限的情况下使用Vim打开它:

navid@navid-ThinkPad-T530:~/ubuntuTest$ vi myFile.txt 

我修改它并按:Esc + : + w + q + Enter我看到此错误消息:

E45: 'readonly' option is set (add ! to override)

到目前为止,一切都有道理。但是当我按下:Esc + : + w + q + ! + Enter时,Vim保存了这些变化。

我正在使用Ubuntu 16.04和VIM 7.4。

最佳解决办法

由于@Rob已经是mentioned,因此只有对包含该文件的目录具有写访问权限时才能执行此操作。尝试对文件执行相同操作(例如,/etc)将失败。

至于vim如何执行此操作,它会删除该文件并重新创建它。为了测试这个,我创建了一个root拥有的文件:

echo foo | sudo tee fff

然后按照您描述的方式继续使用vim编辑文件,但将流程附加到strace以查看发生的情况:

strace vim fff 2> strace.out

然后我检查了strace.out并发现:

unlink("fff")                           = 0
open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "foasdasdao\n", 11)            = 11

因此,首先删除了文件(unlink("fff")),然后创建了一个同名的新文件(open("fff", O_WRONLY|O_CREAT|O_TRUNC, 0644)),并将我所做的修改写入(write(4, "foasdasdao\n", 11))。如果您在家中尝试此操作,您将看到在使用vim编辑它之后,该文件现在将属于您而不是root。

因此,严格来说,vim不会编辑您没有写入权限的文件。它正在从您具有写访问权限的目录中删除文件,然后再创建一个新文件,您也可以对该文件具有写访问权限。

次佳解决办法

只要您拥有父目录,您就可以删除或替换文件,无论权限如何,因为您可以更改目录的内容:)。

尝试使用其他命令,如rm,它会提示你,但你仍然可以做到。使目录不可写,应该停止它。

加成:

刚尝试过,但只要我拥有该文件,我仍然可以修改它,即使文件夹是只读的。但是,当我将所有权更改为root:root时,它无法打开文件进行写入。因此解决了root(或其他人)拥有的修改文件

第三种解决办法

使用w!您将删除原始文件(您可以这样做)并编写您的版本。

当您具有对目录的写入权限时,您可以:创建,移动或删除该目录中的文件。

$ mkdir foo
$ echo hi > foo/file
$ chmod 777 foo
$ chmod 700 foo/file
$ ls -l foo/file 
-rwx------ 1 ravexina ravexina 7 Aug 31 03:19 foo/file

现在让我切换用户并更改文件

$ sudo -u user2 -s
$ vi foo/a # save using w! (I wrote into the file bye)
$ ls -l foo/a
-rwx------ 1 user2 user2 7 Aug 31 03:20 foo/file

现在看看那里有什么:

$ cat foo/file
bye

第四种办法

:help write-readonly

                                                        write-readonly
When the 'cpoptions' option contains 'W', Vim will refuse to overwrite a
readonly file.  When 'W' is not present, ":w!" will overwrite a readonly file,
if the system allows it (the directory must be writable).

由于您对目录具有写权限(意味着您可以在其中创建,删除或重命名文件),因此系统允许它。


cpoptions的默认值不包含W

                                                'cpoptions' 'cpo' cpo
'cpoptions' 'cpo'       string  (Vim default: "aABceFs",
                                 Vi default:  all flags)
                        global

第五种办法

考虑到UNIX中的权限如何工作,这是VIM对您的警告,这可能是相对重要的。这种明显的不直观性是因为UNIX文件系统对存储在文件的i-node中的文件具有权限。目录结构在某种程度上是分开的,只链接这些i-nodes。目录还具有权限,可以说明您是否可以将文件链接/取消链接,或者读取或遍历到sub-directories。此设计允许相同的文件可以出现在目录结构中的几个不同位置(通过硬链接)。通过说“添加!覆盖”VIM试图警告您原始文件将被取消链接(因此它将保持在所有其他位置不受影响)并且将创建新文件并将其链接到目录结构中的原始位置。如果原始文件的link-count减少为零,原始文件将被释放,但如果没有,则表示您正在有效地克隆该文件。打开文件也算作链接,因此如果某个程序打开文件并且您同意“添加!覆盖”,程序将不会看到您使用VIM对文件所做的更改。该文件仅由VIM从目录中取消链接,并且在由另一个程序关闭文件之后,该文件将被释放,除非它被链接到其他位置。

请注意,在Windows中,文件的权限存储在目录中,因此从Windows权限范例的角度来看,这种vim行为可能看起来确实很奇怪。对于写入文件,Windows在逻辑上也可能会检查一些目录权限,甚至是super-directory权限。如上所述,在UNIX中,目录权限与文件的操作无关,只要您能够列出并打开它(即所有super-directories都有x)。如果在打开后从所有目录中取消链接,则UNIX中打开的文件可能不再具有文件名。

例如,你有文件/home /user1 /foo,它与(/hardlinked)/home /user2 /foo是同一个文件,文件不是任何人都可写的,目前由程序P打开(程序启动打开read-write)由根)。如果user1使用vim和覆盖打开它,他会创建自己的副本,不再看到原始文件。如果随后user2打开他与vim的链接并写入其中,它将再次取消链接,他将创建另一个副本。程序P仍然可以看到原始文件,可以自由地读取或写入。一旦程序关闭文件,文件就会消失(由文件系统释放)。

第六种办法

您的vim编辑器进程和您的文件都带有您的

 getpwnam("navid")->pw_uid

所有权,以便你也可以炮轰

 :!chmod +w %

而且你可能会想到,曾经一度更简单

 :!rm %

(仅需要+ w,u-t取消链接权限。甚至不是所有权)变得太频繁,以至于有人打字以便vim被重新编程为自动提供并且根据请求自动执行这样的操作。

试着覆盖你的大姐姐

 /home/whoopi/.profile

仅仅是导航和赌注是你的vim给你你想要的拒绝。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1840.html,未经允许,请勿转载。