为什么我可以修改只读文件?

简短问题:

为什么我们可以使用以下方法操作Vim中的只读文件 + w + q + 即使不是管理员?

长问题:

我有一个文本文件(myFile.txt),对每个人都是只读的:

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已经提到的 ,只有对包含该文件的目录具有写访问权限时才能执行此操作。 尝试对文件执行相同操作(例如/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节点中的文件具有权限。 目录结构以某种方式分离,仅链接这些i节点。 目录还具有权限,可以说明您是否可以将文件链接/取消链接,或者读取或遍历到子目录。 此设计允许相同的文件可以出现在目录结构中的几个不同位置(通过硬链接)。 通过说“添加!覆盖”VIM试图警告您原始文件将被取消链接(因此它将保持在所有其他位置不受影响)并且将创建新文件并将其链接到目录结构中的原始位置。 如果原始文件的链接计数减少为零,则将释放原始文件,但如果不是,则表示您正在有效地克隆该文件。 打开文件也算作链接,因此如果某个程序打开文件并且您同意“添加!覆盖”,程序将不会看到您使用VIM对文件所做的更改。 该文件仅由VIM从目录中取消链接,并且在由另一个程序关闭文件之后,该文件将被释放,除非它被链接到其他位置。

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

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

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

  getpwnam("navid")->pw_uid 

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

  :!chmod +w % 

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

  :!rm % 

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

试着覆盖你的大姐姐

  /home/whoopi/.profile 

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

这不是一个答案,但如果您真的想要设置一个文件,以便没有人可以更改或删除它,您可以使其不可变。

通常,即使文件由root拥有,如果您对该文件夹具有写入权限,仍可以删除该文件。 但是当你使文件不可变时,即使root也无法修改或删除它。

使文件不可变(你需要sudo ):

 sudo chattr +i myFile.txt 

你可以用lsattr (结果中的字母i )看到这个:

 $ lsattr myFile.txt ----i--------e-- myFile.txt 

要使文件再次正常:

 sudo chattr -i myFile.txt 

澄清:当文件是不可变的时,它不能被删除,重命名,修改,甚至硬链接。

值得阅读man chattr ,因为文件可以有许多有用的属性。

您可能还会发现“限制删除”很有用。 如果放在文件夹(而不是文件)上,这意味着允许在文件夹中创建文件的任何人修改或删除该文件,但没有其他人(除root之外)。 文件夹/tmp设置了此标志。 您可以在/tmp上看到t标志:

 $ ls -l --directory /tmp drwxrwxrwt 10 root root 4096 Sep 6 09:00 /tmp 

要设置或删除文件夹上的受限删除标志:

 chmod +t myFolder # Add the restricted deletion flag. chmod -t myFolder # Remove the restricted deletion flag.