Answers:
%
被替换为当前文件名,因此您可以使用:
:w !sudo tee %
(vim
将检测到文件已更改,并询问是否要重新加载该文件。请选择“是”,[L]
而不是“确定”。)
作为快捷方式,您可以定义自己的命令。将以下内容放入您的.vimrc
:
command W w !sudo tee % >/dev/null
通过上面的内容,您可以键入:W<Enter>
以保存文件。自从我写这篇文章以来,我发现了一种更好的方法(我认为):
cmap w!! w !sudo tee >/dev/null %
通过这种方式,您可以输入:w!!
内容并将其扩展到完整的命令行,将光标留在末尾,因此您可以根据需要%
用自己的文件名替换。
sudo: 1 incorrect password attempt
/etc/sudoers
文件,your_username ALL=(ALL) ALL
在该行下添加root ALL=(ALL) ALL
,然后退出并保存。
通常,您不能更改vi进程的有效用户ID,但是可以这样做:
:w !sudo tee myfile
:w !sudo tee % >/dev/null
或:w !sudo dd of=%
避免在保存文件时回显文件的内容。
tee
,发现它是一个Unix管道命令,并!
插入一个shell命令。是:w
对标准的写作tee
吗?
解决只读文件问题的最常见方法是使用的实现以超级用户身份打开到当前文件的管道sudo tee
。但是,我在Internet上发现的所有最流行的解决方案都有以下几个潜在警告:
要解决所有这些问题,可以使用以下命令:
" On POSIX (Linux/Mac/BSD):
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
" Depending on the implementation, you might need this on Windows:
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >NUL'
这些可以缩短,敬请注意:
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'
:
开始命令;您将需要在正常模式下键入此字符以开始输入命令。在脚本中应该省略它。
sil[ent]
禁止命令输出。在这种情况下,我们要停止Press any key to continue
运行:!
命令后出现的-like提示。
exec[ute]
将字符串作为命令执行。我们不能只运行,:write
因为它不会处理必要的函数调用。
!
代表:!
命令:唯一:write
接受的命令。通常,:write
接受要写入的文件路径。 :!
单独在shell中运行命令(例如,使用bash -c
)。使用:write
,它将在外壳中运行命令,然后将整个文件写入stdin
。
sudo
应该很明显,因为这就是为什么你在这里。以超级用户身份运行命令。网上有很多有关其工作原理的信息。
tee
管道stdin
到给定的文件。 :write
将写入stdin
,那么超级用户tee
将接收文件内容并写入文件。它不会创建新文件-只会覆盖内容-因此将保留文件模式和属性。
shellescape()
在给定的文件路径中转义适合当前shell的特殊字符。仅使用一个参数,通常仅在必要时将路径用引号引起来。由于我们要发送到完整的shell命令行,因此我们希望传递一个非零值作为第二个参数,以启用对其他特殊字符的反斜杠转义,否则这些特殊字符可能会触发shell。
@%
读取%
寄存器的内容,其中包含当前缓冲区的文件名。它不一定是绝对路径,所以请确保您没有更改当前目录。在某些解决方案中,您将看到省略商业广告符号。根据位置的不同,%
它是有效的表达式,并且具有与读取%
寄存器相同的效果。但是,嵌套在另一个表达式中的快捷方式通常是不允许的:例如在这种情况下。
>NUL
并>/dev/null
重定向stdout
到平台的空设备。即使我们已经使命令静音,我们也不希望将所有与管道stdin
传递回vim 相关的开销-最好尽早转储。 NUL
是DOS,MS-DOS和Windows上的空设备,不是有效文件。从Windows 8开始,重定向到NUL不会导致写入名为NUL的文件。尝试在桌面上创建一个名为NUL的文件,带有或不带有文件扩展名:您将无法执行此操作。(Windows中还有一些其他的设备名称可能值得了解。)
当然,您仍然不想记住这些内容并每次都键入它们。将适当的命令映射到更简单的用户命令要容易得多。要在POSIX上执行此操作,可以将以下行添加到~/.vimrc
文件中,如果尚不存在,则创建它:
command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
这将允许您键入:W(区分大小写)命令以具有超级用户权限写入当前文件-更加容易。
我使用的是跨平台的~/.vimrc
文件,可以在计算机之间进行同步,因此我添加了多平台功能。这里~/.vimrc
只有相关设置:
#!vim
" Use za (not a command; the keys) in normal mode to toggle a fold.
" META_COMMENT Modeline Definition: {{{1
" vim: ts=4 sw=4 sr sts=4 fdm=marker ff=unix fenc=utf-8
" ts: Actual tab character stops.
" sw: Indentation commands shift by this much.
" sr: Round existing indentation when using shift commands.
" sts: Virtual tab stops while using tab key.
" fdm: Folds are manually defined in file syntax.
" ff: Line endings should always be <NL> (line feed #09).
" fenc: Should always be UTF-8; #! must be first bytes, so no BOM.
" General Commands: User Ex commands. {{{1
command W call WriteAsSuperUser(@%) " Write file as super-user.
" Helper Functions: Used by user Ex commands. {{{1
function GetNullDevice() " Gets the path to the null device. {{{2
if filewritable('/dev/null')
return '/dev/null'
else
return 'NUL'
endif
endfunction
function WriteAsSuperUser(file) " Write buffer to a:file as the super user (on POSIX, root). {{{2
exec '%write !sudo tee ' . shellescape(a:file, 1) . ' >' . GetNullDevice()
endfunction
" }}}1
" EOF
sudo
存在但不存在的情况/dev/null
,因此,如果您想要真正的跨平台支持,则需要变得更高级。更多的是介绍-值得深思。:)
当您对文件进行插入模式时,您需要使用sudo权限进行编辑,您会看到一条状态消息:
-- INSERT -- W10: Warning: Changing a readonly file
如果我想念那,我通常会
:w ~/edited_blah.tmp
:q
..然后..
sudo "cat edited_blah.tmp > /etc/blah"
..要么..
sudo mv edited_blah.tmp /etc/blah
可能有一种不太绕行的方式来做到这一点,但它确实有效。
快速的Google似乎提供了以下建议:
这是自回答此问题以来出现的另一个插件,名为SudoEdit的插件,提供SudoRead和SudoWrite函数,默认情况下将尝试首先使用sudo,如果失败则尝试使用su:http : //www.vim.org/scripts/ script.php?script_id = 2709
我的〜/ .bashrc中有这个:
alias svim='sudo vim'
现在,每当我需要编辑配置文件时,都可以使用svim打开它。
sudoedit
命令应该是首选,因为它不需要以root用户身份运行vim。
您可以考虑的一种快速破解方法是,对正在编辑的文件执行chmod,然后用vim保存,然后将chmod恢复为最初的文件格式。
ls -l test.file (to see the permissions of the file)
chmod 777 test.file
[This is where you save in vim]
chmod xxx test.file (restore the permissions you found in the first step)
当然,我不建议在担心安全性的系统中使用这种方法,因为有几秒钟的时间,任何人都可以在不知不觉中读取/更改文件。