为什么我可以修改只读文件?
简短问题:
为什么我们可以使用以下方法操作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.