问题描述
简短问题:
为什么我们可以使用:
+ 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给你你想要的拒绝。