Linux 获取vi中文件的root权限?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting root permissions on a file inside of vi?
提问by Paul Wicks
Often while editing config files, I'll open one with vi and then when I go to save it realize that I didn't type
通常在编辑配置文件时,我会用 vi 打开一个,然后当我去保存它时意识到我没有输入
sudo vi filename
Is there any way to give vi sudo privileges to save the file? I seem to recall seeing something about this while looking up some stuff about vi a while ago, but now I can't find it.
有没有办法给 vi sudo 权限来保存文件?我似乎记得前段时间在查找有关 vi 的一些内容时看到了一些关于此的内容,但现在我找不到了。
采纳答案by dbr
%
is replaced with the current file name, thus you can use:
%
替换为当前文件名,因此您可以使用:
:w !sudo tee %
(vim
will detect that the file has been changed and ask whether you want to it to be reloaded. Say yes by choosing [L]
rather than OK.)
(vim
将检测到文件已被更改并询问您是否要重新加载它。选择“是”[L]
而不是“确定”。)
As a shortcut, you can define your own command. Put the following in your .vimrc
:
作为一种快捷方式,您可以定义自己的命令。将以下内容放入您的.vimrc
:
command W w !sudo tee % >/dev/null
With the above you can type :W<Enter>
to save the file. Since I wrote this, I have found a nicer way (in my opinion) to do this:
使用上述内容,您可以键入:W<Enter>
以保存文件。自从我写这篇文章以来,我找到了一个更好的方法(在我看来)来做到这一点:
cmap w!! w !sudo tee >/dev/null %
This way you can type :w!!
and it will be expanded to the full command line, leaving the cursor at the end, so you can replace the %
with a file name of your own, if you like.
通过这种方式,您可以键入:w!!
,它将扩展为完整的命令行,将光标留在末尾,因此您可以根据需要将 替换%
为您自己的文件名。
回答by Ryan Fox
A quick Google seems to give this advice:
一个快速的谷歌似乎给出了这个建议:
- Don't try to edit if it's read-only.
- You might be able to change the permissions on the file. (Whether or not it will let you save is up to experimentation.)
- If you still edited anyway, save to a temporary file and then move it.
- 如果它是只读的,请不要尝试编辑。
- 您也许能够更改文件的权限。(它是否会让你保存取决于实验。)
- 如果您仍然编辑,请保存到临时文件,然后移动它。
回答by Chris Jester-Young
Ryan's advice is generally good, however, if following step 3, don't move the temporary file; it'll have the wrong ownership and permissions. Instead, sudoedit
the correct file and read in the contents (using :r
or the like) of the temporary file.
Ryan 的建议通常是好的,但是,如果遵循第 3 步,请不要移动临时文件;它将拥有错误的所有权和权限。相反,sudoedit
正确的文件并读取:r
临时文件的内容(使用等)。
If following step 2, use :w!
to force the file to be written.
如果按照第 2 步,使用:w!
强制写入文件。
回答by Mark Harrison
In general, you can't change the effective user id of the vi process, but you can do this:
通常,您无法更改 vi 进程的有效用户 ID,但您可以这样做:
:w !sudo tee myfile
回答by num1
A quick hack you can consider is doing a chmod on the file you're editing, save with vim, and then chmod back to what the file was originally.
您可以考虑的一个快速技巧是对您正在编辑的文件执行 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)
Of course I don't recommend this approach in a system where you're worried about security, as for a few seconds anyone can read/change the file without you realizing.
当然,我不建议在您担心安全性的系统中使用这种方法,因为在几秒钟内任何人都可以在您没有意识到的情况下读取/更改文件。
回答by dbr
When you go into insert mode on a file you need sudo access to edit, you get a status message saying
当您在需要 sudo 访问权限才能编辑的文件上进入插入模式时,您会收到一条状态消息说
-- INSERT -- W10: Warning: Changing a readonly file
If I miss that, generally I do
如果我错过了,通常我会
:w ~/edited_blah.tmp
:q
..then..
..然后..
sudo "cat edited_blah.tmp > /etc/blah"
..or..
..或者..
sudo mv edited_blah.tmp /etc/blah
There's probably a less roundabout way to do it, but it works.
可能有一种不那么迂回的方法来做到这一点,但它有效。
回答by ephemient
回答by pisswillis
I have this in my ~/.bashrc:
我的 ~/.bashrc 中有这个:
alias svim='sudo vim'
Now whenever I need to edit a config file I just open it with svim.
现在,每当我需要编辑配置文件时,我只需使用 svim 打开它。
回答by James Snyder
Here's another one that has appeared since this question was answered, a plugin called SudoEdit which provides SudoRead and SudoWrite functions, which will by default try to use sudo first and su if that fails: http://www.vim.org/scripts/script.php?script_id=2709
这是自从回答这个问题后出现的另一个插件,一个名为 SudoEdit 的插件,它提供了 SudoRead 和 SudoWrite 函数,默认情况下,它将首先尝试使用 sudo,如果失败,则尝试使用 su:http: //www.vim.org/scripts/ script.php?script_id=2709
回答by Zenexer
Common Caveats
常见警告
The most common method of getting around the read-only file problem is to open a pipe to current file as the super-user using an implementation of sudo tee
. However, all of the most popular solutions that I have found around the Internet have a combination of a several potential caveats:
解决只读文件问题的最常见方法是以超级用户身份使用sudo tee
. 但是,我在 Internet 上找到的所有最流行的解决方案都有几个潜在警告的组合:
- The entire file gets written to the terminal, as well as the file. This can be slow for large files, especially over slow network connections.
- The file loses its modes and similar attributes.
- File paths with unusual characters or spaces might not be handled correctly.
- 整个文件和文件都被写入终端。对于大文件,这可能会很慢,尤其是在网络连接速度较慢的情况下。
- 该文件失去了它的模式和类似的属性。
- 带有异常字符或空格的文件路径可能无法正确处理。
Solutions
解决方案
To get around all of these issues, you can use the following command:
要解决所有这些问题,您可以使用以下命令:
" 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'
These can be shortened, respectfully:
这些可以缩短,恭敬地:
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'
Explanation
解释
:
begins the command; you will need to type this character in normal mode to start entering a command. It should be omitted in scripts.
:
开始命令;您需要在正常模式下键入此字符才能开始输入命令。它应该在脚本中省略。
sil[ent]
suppresses output from the command. In this case, we want to stop the Press any key to continue
-like prompt that appears after running the :!
command.
sil[ent]
抑制命令的输出。在这种情况下,我们希望停止Press any key to continue
运行:!
命令后出现的-like 提示。
exec[ute]
executes a string as a command. We can't just run :write
because it won't process the necessary function call.
exec[ute]
将字符串作为命令执行。我们不能只运行,:write
因为它不会处理必要的函数调用。
!
represents the :!
command: the only command that :write
accepts. Normally, :write
accepts a file path to which to write. :!
on its own runs a command in a shell (for example, using bash -c
). With :write
, it will run the command in the shell, and then write the entire file to stdin
.
!
代表:!
命令:唯一:write
接受的命令。通常,:write
接受要写入的文件路径。 :!
单独在 shell 中运行命令(例如,使用bash -c
)。使用:write
,它将在 shell 中运行命令,然后将整个文件写入stdin
.
sudo
should be obvious, since that's why you're here. Run the command as the super-user. There's plenty of information around the 'net about how that works.
sudo
应该很明显,因为这就是你在这里的原因。以超级用户身份运行该命令。网络上有很多关于它是如何工作的信息。
tee
pipes stdin
to the given file. :write
will write to stdin
, then the super-user tee
will receive the file contents and write the file. It won't create a new file--just overwrite the contents--so file modes and attributes will be preserved.
tee
stdin
到给定文件的管道。 :write
将写入stdin
,然后超级用户tee
将接收文件内容并写入文件。它不会创建新文件——只是覆盖内容——所以文件模式和属性将被保留。
shellescape()
escapes special characters in the given file path as appropriate for the current shell. With just one parameter, it would typically just enclose the path in quotes as necessary. Since we're sending to a full shell command line, we'll want to pass a non-zero value as the second argument to enable backslash-escaping of other special characters that might otherwise trip up the shell.
shellescape()
转义给定文件路径中适合当前 shell 的特殊字符。只有一个参数,它通常会根据需要用引号将路径括起来。由于我们要发送到完整的 shell 命令行,因此我们希望传递一个非零值作为第二个参数,以启用其他特殊字符的反斜杠转义,否则这些特殊字符可能会导致 shell 跳闸。
@%
reads the contents of the %
register, which contains the current buffer's file name. It's not necessarily an absolute path, so ensure that you haven't changed the current directory. In some solutions, you will see the commercial-at symbol omitted. Depending on the location, %
is a valid expression, and has the same effect as reading the %
register. Nested inside another expression the shortcut is generally disallowed, however: such as in this case.
@%
读取%
寄存器的内容,其中包含当前缓冲区的文件名。它不一定是绝对路径,因此请确保您没有更改当前目录。在某些解决方案中,您会看到省略了 Commercial-at 符号。取决于位置,%
是一个有效的表达式,与读取%
寄存器的效果相同。嵌套在另一个表达式中的快捷方式通常是不允许的,但是:例如在这种情况下。
>NUL
and >/dev/null
redirect stdout
to the platform's null device. Even though we've silenced the command, we don't want all of the overhead associated with piping stdin
back to vim--best to dump it as early as possible. NUL
is the null device on DOS, MS-DOS, and Windows, not a valid file. As of Windows 8 redirections to NUL don't result in a file named NUL being written. Try creating a file on your desktop named NUL, with or without a file extension: you will be unable to do so. (There are several other device names in Windows that might be worth getting to know.)
>NUL
并>/dev/null
重定向stdout
到平台的空设备。即使我们已经关闭了该命令,我们也不希望与管道相关的所有开销都stdin
返回到 vim——最好尽早转储它。 NUL
是 DOS、MS-DOS 和 Windows 上的空设备,不是有效文件。从 Windows 8 开始,重定向到 NUL 不会导致写入名为 NUL 的文件。尝试在您的桌面上创建一个名为 NUL 的文件,带有或不带有文件扩展名:您将无法这样做。(Windows 中还有其他几个设备名称可能值得了解。)
~/.vimrc
~/.vimrc
Platform-Dependent
平台相关
Of course, you still don't want to memorize those and type them out each time. It's much easier to map the appropriate command to a simpler user command. To do this on POSIX, you could add the following line to your ~/.vimrc
file, creating it if it doesn't already exist:
当然,您仍然不想记住这些并每次都输入它们。将适当的命令映射到更简单的用户命令要容易得多。要在 POSIX 上执行此操作,您可以将以下行添加到您的~/.vimrc
文件中,如果它不存在则创建它:
command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
This will allow you to type the :W (case-sensitive) command to write the current file with super-user permissions--much easier.
这将允许您键入 :W(区分大小写)命令以使用超级用户权限写入当前文件——更容易。
Platform-Independent
平台无关
I use a platform-independent ~/.vimrc
file that synchronizes across computers, so I added multi-platform functionality to mine. Here's a ~/.vimrc
with only the relevant settings:
我使用~/.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