以普通用户启动的Vim如何保存需要root权限的文件
在Linux上工作的朋友很可能遇到过这样一种情况,当你用Vim编辑完一个文件时,运行 E45:'readonly'optionisset(add!tooverride) 这表明文件是只读的,按照提示,加上 "readonly-file-name"E212:Can'topenfileforwriting 文件明明存在,为何提示无法打开?这错误又代表什么呢?查看文档 Forsomereasonthefileyouarewritingtocannotbecreatedoroverwritten. Thereasoncouldbethatyoudonothavepermissiontowriteinthedirectory orthefilenameisnotvalid. 原来是可能没有权限造成的。此时你才想起,这个文件需要root权限才能编辑,而当前登陆的只是普通用户,在编辑之前你忘了使用 但这样操作过于繁琐。而且如果只是想暂存此文件,还需要接着修改,则希望保留Vim的工作状态,比如编辑历史,buffer状态等等,该怎么办?能不能在不退出Vim的情况下获得root权限来保存这个文件? 解决方案答案是可以,执行这样一条命令即可: :w!sudotee% 接下来我们来分析这个命令为什么可以工作。首先查看文档 *:w_c**:write_c* :[range]w[rite][++opt]!{cmd} Execute{cmd}with[range]linesasstandardinput (notethespaceinfrontofthe'!').{cmd}is executedlikewith":!{cmd}",any'!'isreplacedwith thepreviouscommand|:!|. Thedefault[range]forthe":w"commandisthewholebuffer(1,$) 把这个使用方法对应前面的命令,如下所示: :w!sudotee% |||| :[range]w[rite][++opt]!{cmd} 我们并未指定 Vim中执行外部命令接下来是一个叹号 :r!pwd或:r!ls 此时所有的内容便被读入至Vim,而不需要退出Vim,执行命令,然后拷贝粘贴至Vim中。有了它,Vim可以自由的操作shell而无需退出。 命令的另一种表示形式再看前面的文档: Execute{cmd}with[range]linesasstandardinput 所以实际上这个 $catreadonly-file-name|sudotee% 这样看起来”正常”些了。其中 %的意义我们先来看 InExcommands,atplaceswhereafilenamecanbeused,thefollowing charactershaveaspecialmeaning.Thesecanalsobeusedintheexpression functionexpand()|expand()|. % Isreplacedwiththecurrentfilename. *:_%**c_%* 在执行外部命令时, $catreadonly-file-name|sudoteereadonly-file-name 注意:在另外一个地方我们也经常用到 Linenumbersmaybespecifiedwith: *:range**E14**{address}* {number} anabsolutelinenumber ... % equalto1,$(theentirefile) *:%* 在替换中, tee的作用现在只剩一个难点: tee。它究竟有何用?维基百科上对其有一个详细的解释,你也可以查看man page。下面这幅图很形象的展示了
现在上面的命令就容易理解了, 命令执行之后运行完上述命令后,会出现下面的提示: W12:Warning:File"readonly-file-name"haschangedandthebufferwaschangedinVimaswell See":helpW12"formoreinfo. [O]K,(L)oadFile: Vim提示文件更新,询问是确认还是重新加载文件。建议直接输入 更简单的方案:映射上述方式非常完美的解决了文章开始提出的问题,但毕竟命令还是有些长,为了避免每次输入一长串的命令,可以将它映射为一个简单的命令加到 1"AllowsavingoffilesassudowhenIforgottostartvimusingsudo.2cmapw!!w!sudotee>/dev/null% 这样,简单的运行 另一种思路至此,一个比较完美但很tricky的方案已经完成。你可能会问,为什么不用下面这样更常见的命令呢?这不是更容易理解,更简单一些么? :w!sudocat>% 重定向的问题我们来分析一遍,像前面一样,它可以被转换为相同功能的shell命令: $catreadonly-file-name|sudocat>% 这条命令看起来一点问题没有,可一旦运行,又会出现另外一个错误: /bin/sh:readonly-file-name:Permissiondenied shellreturned1 这是怎么回事?不是明明加了 重定向方案这里介绍了几种解决重定向无权限错误的方法,当然除了 :w!sudosh-c'cat>%' 可是这样执行时,由于单引号的存在,所以在Vim中 既然是由于 :w!sudosh-c"cat>%" 成功!这是因为在将命令传到shell去之前, 当然,也可以像前面一样将它映射为一个简单的命令并添加到.vimrc中: 1"AllowsavingoffilesassudowhenIforgottostartvimusingsudo.2cmapw!!w!sudosh-c"cat>%" 注意:这里不再需要把输出重定向到 写在结尾至此,借助Vim强大的灵活性,实现了两种方案,可以在以普通用户启动的Vim中保存需root权限的文件。两者的原理类似,都是利用了Vim可以执行外部命令这一特性,区别在于使用不同的shell命令 转贴,原文地址:feihu.me/blog/2014/vim-write-read-only-file/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |