以非root用户身份编辑文件后如何将其保存为root用户?

25

好的,这种情况经常发生在我身上。肯定有更好的解决方案。假设你执行了vim /etc/somefile.conf 然后你按了 i 但是意识到你没有使用 sudo 权限,不能写入文件。然后我通过执行 :q 再执行 sudo !! 并再次进行更改来避免丢失我的更改。是否有更好的方法?

7个回答

46

试一试

:w !sudo tee "%"

w !取整个文件并将其传递给Shell命令。Shell命令是sudo tee,它作为超级用户运行tee%会被当前文件名替换。对于名称中包含空格或任何其他特殊字符的文件,需要使用引号。


3
":w!" 和 ":w !" 是非常不同的,现在我知道了。 :)" - Amir Raminfar
2
这就是为什么我从不使用Vim。同时感谢您让我的声望超过10,000分。 :) - Joel Spolsky
7
为了达到这个目的,我在我的 .vimrc 文件里加入了以下内容:"cmap w!! w !sudo tee % > /dev/null"。该命令可以让你在 Vim 编辑器中通过输入 "w!!" 将当前文件保存并使用 sudo 权限将其写入磁盘,而无需在终端中执行额外的命令。 - kejadlen
@kejadlen - 这是一个很棒的解决方案! - Amir Raminfar
这种方法对于文件名中带有空格的文件无效。正确的通用答案应该是 :w !sudo tee "%". - Victor Yarema

2
根据您所做的更改的程度,将文件另存为不同的名称可能会更快,然后使用sudo和cat覆盖原始文件的内容:sudo sh -c 'cat changed > file'。请注意,cp和mv都将替换原始文件,并且其属性(所有权、权限、ACL)将丢失。除非您知道如何修复权限,否则不要使用它们

1

将文件保存到其他地方(比如你的主文件夹),然后使用sudo mv命令覆盖原文件?


1
我建议使用 cat changed > file 来保留原始文件属性。对于此操作,使用 mv 是一种灾难性的做法。 - thkala
一旦您已经以非root用户身份进行了更改,那么在vim中执行此操作的命令是什么? - WhiteHotLoveTiger

0

我使用了这个:

function! SaveAsSudo()
    let v=winsaveview()
    let a=system("stat -c \%a " .  shellescape(expand('%')))
    let a=substitute(a,"\n","","g")
    let a=substitute(a,"\r","","g")
    call system("sudo chmod 666 " . shellescape(expand('%')))
    w
    call system("sudo chmod " . a . " " . shellescape(expand('%')))
    call winrestview(v)
endfunction

我已将<F2>映射到:w<CR>,并将<F8>映射到:call SaveAsSudo()<CR>

这个答案相对于sudo tee选项的唯一优点是:vim不会抱怨未保存的缓冲区或外部修改的文件。


你的程序跑得很快。当然,在个人电脑上这可能并不重要。 - Michał Politowski
是的,我只打算在我的个人电脑上运行它。 :-) - anishsane

0

将更改保存为另一个文件,然后进行适当的替换。


0

当Vim启动时,状态栏会显示[只读],当你第一次尝试进行编辑时,它会显示W10:警告:更改只读文件,并暂停了整整一秒钟。这已经足够让我警觉并退出并输入sudoedit /etc/somefile.conf

您可以使用插件强制实现这一点:使缓冲区修改状态与文件只读状态匹配


是的,我意识到了,但是这个警告并不总是在每个系统上都一致。有些Linux版本不会显示警告。 - Amir Raminfar

0

我使用zsh模板和函数完成。

具体来说是这个。如果我没有写入权限,它会提示我输入sudo密码并自动运行"sudo vim"……等等其他操作。


这是一个好主意。然而,这里有一个问题 - 我们并不总是在命令行中将文件作为单独的文件打开。通常文件是从vim中使用:e或从(c)tags中打开的。在那里,shell函数将无法帮助。 - anishsane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接