游乐游手机版
首页/系统平台/文章详情

Linux普通用户vi/vim编辑文件无保存权限的解决方法

时间:2026-06-25 07:36
在 Linux 环境中使用 Vim 编辑器的用户,几乎都遇到过这样的尴尬场景:用 vi 或 vim 打开一个文件,费心费力修改了大量内容,最后输入 :wq 准备保存退出,却看到屏幕弹出红色警告—— E45: readonly option is set (add ! to override) 原

在 Linux 环境中使用 Vim 编辑器的用户,几乎都遇到过这样的尴尬场景:用 vi 或 vim 打开一个文件,费心费力修改了大量内容,最后输入 :wq 准备保存退出,却看到屏幕弹出红色警告——

E45: 'readonly' option is set (add ! to override)

原来文件被设置为只读。你可能会想,加个感叹号强制保存总可以吧?于是输入 :w!,结果又出现提示:

"readonly-file-name" E212: Can't open file for writing

文件明明就在那里,为什么无法写入?查看 Vim 文档 :help E212 之后会发现,根本原因是权限不足。这个文件需要 root 权限才能编辑,而你当初只是用普通用户登录,启动 vim 时忘记加上 sudo。这样一来,之前辛辛苦苦修改的内容难道就要丢失吗?

常见的做法是:先另存为一个临时文件,退出 vim,再用 sudo mv 覆盖原文件。操作起来不算太难,但麻烦的是 Vim 的工作状态——编辑历史、缓冲区内容、撤销链——全都会丢失。如果只想临时保存一下然后继续修改,有没有办法在不退出 Vim 的情况下获取 root 权限来保存文件呢?

解决方案

当然有。只需执行一条 Vim 命令:

:w !sudo tee %

接下来我们拆解分析这条命令究竟做了什么。先查看 Vim 文档 :help :w,找到关于 :w_c 的说明:

*:w_c* *:write_c*
:[range]w[rite] [++opt] !{cmd}
Execute {cmd} with [range] lines as standard input
(note the space in front of the '!').  {cmd} is
executed like with ":!{cmd}", any '!' is replaced with
the previous command |:!|.
The default [range] for the ":w" command is the whole buffer (1,$)

将这个用法对应到我们的命令上:

:       w               !sudo tee %

没有指定 range,所以默认范围是整个文件。没有指定 opt。后面的 ! 表示后面跟着的外部命令,也就是 sudo tee %。这和直接执行 :!{cmd} 效果一样——在不退出 Vim 的情况下打开 shell 执行一条命令。平时我们常用的 :r !pwd:r !ls 也是同样的原理,它们能把 shell 命令的输出直接读入到当前缓冲区。

注意,这里的 :w 并非真正保存当前文件,它更像“另存为”:把当前缓冲区的所有内容作为标准输入,传给后面的命令。所以整条命令等价于在 shell 中执行:

$ cat readonly-file-name | sudo tee %

其中 % 是什么呢?:help cmdline-special 说得很清楚:在外部命令中,% 会被替换为当前文件的文件名。因此上面的 shell 命令就变成:

$ cat readonly-file-name | sudo tee readonly-file-name

这里可能会有人混淆:在替换命令 :%s/old/new/g 中,% 代表整个文件,而不是文件名。这是两个不同语境下的用法,千万别搞混了。

再说 tee。查看 man 手册可知:它就像一个大写的字母 T,把数据流一分为二——一份写入文件,一份继续流向标准输出。示意图里画得很形象:左边管道传进来的数据经过 tee,右边分叉,一路进文件,一路继续往下传。在我们的命令中,tee 把标准输入的内容写入了 readonly-file-name,另一路标准输出因为没有接收者,相当于被丢弃了。当然你也可以在后面加 > /dev/null 显式扔掉,但没必要多打那几个字符。

执行完这条命令后,Vim 会提示:

W12: Warning: File "readonly-file-name" has changed and the buffer was changed in Vim as well
[O]K, (L)oad File:

建议直接按 O 确认(回车即可),这样 Vim 的工作状态、撤销历史、缓冲区内容都保留下来了。如果选 L 重新加载文件,那就等于打开一个全新的文件,之前的所有修改历史都会丢失。

更省事的方案:做个映射

每次都输入一长串命令毕竟麻烦,可以在 .vimrc 中添加一个快捷映射:

" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %

以后直接输入 :w!! 就能达到同样效果。末尾的 > /dev/null 只是显式丢弃标准输出,不写也行。

另一种思路:为什么不用 cat + 重定向?

看到这里你可能会有疑问:这不就是 cat 加上重定向的事情么?为什么不用下面这种更直觉的写法?

:w !sudo cat > %

试试看,结果又是一个错误:

/bin/sh: readonly-file-name: Permission denied

明明加了 sudo,为什么还是说没有权限?问题出在重定向本身。Shell 在执行任何命令之前,会先对重定向进行处理。而当前的 shell 是以普通用户身份运行的,它根本没有权限去打开那个只读文件进行写入。重定向操作不受 sudo 影响,所以错误就发生了。

有人可能会建议换一种写法:

:w !sudo sh -c 'cat > %'

但这里有一个陷阱:% 在单引号内不会被 Vim 展开,而是原封不动传给 shell。而 shell 会把单独的 % 当作空参数,结果文件内容被写到了 nil,保存失败,内容全部丢失。把单引号换成双引号就能解决:

:w !sudo sh -c "cat > %"

因为双引号里的 % 会在传给 shell 之前被 Vim 展开成真实的文件名。同样,这个命令也能映射成简洁的 :w!!

cmap w!! w !sudo sh -c "cat > %"

注意,这个版本不需要 > /dev/null 了。

两种方案原理相通,都是借助 Vim 能执行外部命令的能力,用不同的 shell 命令绕过了权限限制。如果你还有其他酷炫的玩法,欢迎交流。

来源:https://www.jb51.net/LINUXjishu/608817.html
上一篇Linux服务器加把锁:简易安全加固方法 下一篇Linux Ext2/Ext3/Ext4文件系统知识详解
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
微软详解Win11时间点还原 默认每24小时创建恢复点
系统平台 · 2026-06-30

微软详解Win11时间点还原 默认每24小时创建恢复点

微软今日推送了最新的 6 月可选更新,并发布博客详细解读了 Win11 全新的“时间点还原”(Point-in-time restore)功能——这一功能本质上是对系统恢复体验的一次全面升级,旨在让用户更轻松地应对电脑故障。 微软表示,面向 Windows 11 客户端用户的“时间点还原”功能现已正

Win11 26H1六月可选更新KB5095091 优化放大镜改善装机体验
系统平台 · 2026-06-30

Win11 26H1六月可选更新KB5095091 优化放大镜改善装机体验

微软今天推送了Windows 11 26H1设备的6月可选更新KB5095091,安装完成后系统版本号会升级到Build 28000 2340。值得一提的是,这次更新并非面向所有设备,而是专门为搭载高通骁龙X2系列芯片的机型准备的——包括骁龙X2 Plus、X2 Elite和X2 Elite Ext

Win11六月可选更新KB5095093修复回收站弹窗异常
系统平台 · 2026-06-30

Win11六月可选更新KB5095093修复回收站弹窗异常

微软已悄然推送Windows 11六月可选更新,编号KB5095093。本次更新覆盖两个版本:24H2用户安装后版本号升级至Build 26100 8737,而25H2用户则更新至Build 26200 8737。 本次更新并非仅是小修小补,而是带来了多项实质性新功能。下面我们就来详细解析这些更新内

苹果macOS 27 Beta2封堵Siri AI跳过候补名单漏洞
系统平台 · 2026-06-30

苹果macOS 27 Beta2封堵Siri AI跳过候补名单漏洞

科技媒体 Cult of Mac 昨日(6月23日)发布博文指出,苹果在 macOS 27 Beta 2 更新中悄然封堵了一个此前可用的后门——用户曾能通过一条终端命令绕过候补名单,直接启用新版 Siri AI,如今这一方法已失效。 简要回顾一下:在 macOS 27 Beta 1 阶段,只需在 M

微软加速Win11 25H2推送 覆盖所有符合条件家用PC
系统平台 · 2026-06-30

微软加速Win11 25H2推送 覆盖所有符合条件家用PC

近日(6月23日),科技媒体 Windows Latest 发布了一则值得关注的动态:微软已进一步扩大 Windows 11 25H2 的推送范围,所有满足硬件要求、且不受 IT 部门管理的家庭版和专业版设备,现在均可顺利接收本次更新。 此次升级有一个显著特点——采用“启用包”(eKB)方式进行推送