获取vi内部文件的root权限?

时间:2008-08-04 03:34:03

标签: linux unix vi

通常在编辑配置文件时,我会用vi打开一个,然后当我去保存它时意识到我没有输入

sudo vi filename

有没有办法提供vi sudo权限来保存文件?我似乎记得在不久前查看关于vi的一些内容时看到了一些关于这个的东西,但现在我找不到了。

11 个答案:

答案 0 :(得分:288)

%将替换为当前文件名,因此您可以使用:

:w !sudo tee %

vim会检测到文件已被更改并询问您是否要重新加载。请选择[L]而不是OK,然后选择。)

作为快捷方式,您可以定义自己的命令。将以下内容放入.vimrc

command W w !sudo tee % >/dev/null

通过以上操作,您可以输入:W<Enter>来保存文件。自从我写这篇文章以来,我发现了一种更好的方法(在我看来):

cmap w!! w !sudo tee >/dev/null %

通过这种方式,您可以键入:w!!,它将扩展到完整的命令行,将光标留在最后,这样您就可以用自己的文件名替换%,如果你喜欢。

答案 1 :(得分:32)

通常,您无法更改vi进程的有效用户ID,但您可以执行此操作:

:w !sudo tee myfile

答案 2 :(得分:15)

常见警告

解决只读文件问题的最常用方法是使用sudo tee的实现作为超级用户打开当前文件的管道。但是,我在互联网上找到的所有最流行的解决方案都有几个潜在的警告:

  • 将整个文件写入终端以及文件。对于大型文件,这可能会很慢,尤其是在网络连接速度较慢时。
  • 文件丢失了模式和类似属性。
  • 可能无法正确处理具有异常字符或空格的文件路径。

解决方案

要解决所有这些问题,您可以使用以下命令:

" 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命令后出现的类似:!的提示。

exec[ute]执行字符串作为命令。我们不能只运行:write因为它不会处理必要的函数调用。

!表示:!命令::write接受的唯一命令。通常,:write接受要写入的文件路径。 :!自己在shell中运行命令(例如,使用bash -c)。使用:write,它将在shell中运行命令,然后将整个文件写入stdin

sudo应该是显而易见的,因为这就是你在这里的原因。以超级用户身份运行该命令。关于网络如何运作,有大量的信息。

tee管道stdin到给定文件。 :write将写入stdin,然后超级用户tee将接收文件内容并写入文件。它不会创建新文件 - 只是覆盖内容 - 因此将保留文件模式和属性。

shellescape()转义给定文件路径中的特殊字符,以适合当前shell。只有一个参数,它通常只是根据需要将路径括在引号中。因为我们要发送一个完整的shell命令行,所以我们要传递一个非零值作为第二个参数,以启用其他特殊字符的反斜杠转义,否则可能会破坏shell。

@%读取%寄存器的内容,该寄存器包含当前缓冲区的文件名。它不一定是绝对路径,因此请确保您没有更改当前目录。在某些解决方案中,您将看到省略了commercial-at符号。根据位置,%是一个有效的表达式,与读取%寄存器具有相同的效果。嵌套在另一个表达式中通常不允许使用快捷方式:例如在这种情况下。

>NUL>/dev/nullstdout重定向到平台的空设备。即使我们已经使命令静音,我们也不希望所有与管道stdin相关的开销回到vim - 最好尽早转储它。 NUL是DOS,MS-DOS和Windows上的空设备,而不是有效文件。从Windows 8到NUL的重定向不会导致写入名为NUL的文件。尝试在桌面上创建名为NUL的文件,无论是否有文件扩展名:您将无法执行此操作。 (Windows中有许多其他设备名称可能值得了解。)

的〜/ .vimrc

平台相关

当然,您仍然不想记住这些并且每次都输入它们。将适当的命令映射到更简单的用户命令要容易得多。要在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

答案 3 :(得分:11)

如果您使用的是Vim,则会有一个名为sudo.vim的脚本。如果您发现已打开需要root访问权限的文件,请键入

:e sudo:%
Vim将%替换为当前文件的名称,sudo:指示sudo。用于阅读和写作的vim脚本。

答案 4 :(得分:7)

Ryan的建议总体上是好的,但是,如果按照步骤3,不要移动临时文件;它将拥有错误的所有权和权限。相反,sudoedit正确的文件并读入临时文件的内容(使用:r等)。

如果执行步骤2,请使用:w!强制写入文件。

答案 5 :(得分:3)

当您在文件上进入插入模式时,您需要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

可能有一种不那么迂回的方式,但它确实有效。

答案 6 :(得分:1)

快速谷歌似乎提出了这个建议:

  1. 如果它是只读的,请不要尝试编辑。
  2. 您可以更改文件的权限。 (它是否会让你省钱取决于实验。)
  3. 如果您仍然进行了编辑,请保存到临时文件然后移动它。
  4. http://ubuntuforums.org/showthread.php?t=782136

答案 7 :(得分:1)

这是另一个在问题得到解答后出现的插件,一个名为SudoEdit的插件,它提供了SudoRead和SudoWrite函数,默认情况下首先尝试使用sudo,如果失败则尝试使用su:http://www.vim.org/scripts/script.php?script_id=2709

答案 8 :(得分:0)

我在〜/ .bashrc中有这个:

alias svim='sudo vim'

现在每当我需要编辑配置文件时,我只需用svim打开它。

答案 9 :(得分:-2)

你可以考虑的一个快速入侵是在你正在编辑的文件上做一个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)

当然,我不建议在您担心安全性的系统中使用这种方法,因为几秒钟内任何人都可以在没有意识到的情况下读取/更改文件。

答案 10 :(得分:-7)

使用 gksudo 代替 sudo 用于GVim,即

cmap w!! w !gksudo tee >/dev/null %