很多人可能已经看到了允许你在需要root权限的文件上写的命令,即使你忘了用sudo打开vim:

:w !sudo tee %

问题是我不知道这里到底发生了什么。

我已经想到了这个: w就是为了这个

                                                        *: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} isexecuted like with ":!{cmd}", any '!' is replaced withthe previous command |:!|.

所以它将所有行作为标准输入传递。

!sudo tee部分以管理员权限呼叫tee

为了让所有人都有意义, %应输出文件名(作为tee的参数),但我找不到有关此行为的帮助的参考。

tl; dr有人可以帮我剖析这个命令吗?


#1楼

这也很有效:

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

这是受@Nathan Long评论的启发。

通知

"必须使用'而不是'因为我们希望在传递给shell之前扩展%


#2楼

在执行的命令行中, %代表当前文件名 。 这记录在:help cmdline-special

In Ex commands, at places where a file name can be used, the following
characters have a special meaning.%       Is replaced with the current file name.

正如您已经发现的那样:w !cmd将当前缓冲区的内容传递给另一个命令。 tee所做的是将标准输入复制到一个或多个文件,也复制到标准输出。 因此, :w !sudo tee % > /dev/null 在root时有效地将当前缓冲区的内容写入当前文件。 另一个可用于此的命令是dd

:w !sudo dd of=% > /dev/null

作为快捷方式,您可以将此映射添加到.vimrc

" Force saving files that require root permission
cnoremap w!! w !sudo tee > /dev/null %

使用上面的内容,您可以键入:w!!<Enter>以root身份保存文件。


#3楼

接受的答案涵盖了所有内容,因此我将仅举一个我使用的快捷方式示例,用于记录。

将它添加到etc/vim/vimrc (或~/.vimrc ):

  • cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!

哪里:

  • cnoremap :告诉vim在命令行中关联以下快捷方式。
  • w!! :快捷方式本身。
  • execute '...' :执行以下字符串的命令。
  • silent! :默默地运行它
  • write !sudo tee % >/dev/null :OP问题,添加了一个消息重定向到NULL来做一个干净的命令
  • <bar> edit! :这个技巧是蛋糕的樱桃:它还调用edit命令重新加载缓冲区,然后避免缓冲区等消息发生变化<bar>是如何编写管道符号以在此处分隔两个命令。

希望能帮助到你。 另见其他问题:

  • 超级用户:强制vim写一个文件

#4楼

我想建议另一种方法来解决“打开我的文件时忘了写sudo Oups”问题:

而不是接受permission denied ,并且必须输入:w!! ,如果文件所有者是root ,我发现有一个条件vim命令可以执行sudo vim更优雅。

这很容易实现(甚至可能有更优雅的实现,我显然不是bash-guru):

function vim(){OWNER=$(stat -c '%U' $1)if [[ "$OWNER" == "root" ]]; thensudo /usr/bin/vim $*;else/usr/bin/vim $*;fi
}

它的效果非常好。

这是一个比较bash -centered方法比vim酮所以不是每个人可能会喜欢它。

当然:

  • 有些用例会失败(当文件所有者不是root但需要sudo ,但无论如何都可以编辑该函数)
  • 当使用vim只读文件时没有意义(就我而言,我使用tailcat作为小文件)

但我发现这会带来更好的开发用户体验 ,这是恕我直言,在使用bash时会被遗忘的东西。 :-)


#5楼

:w - 写一个文件。

!sudo - 调用shell sudo命令。

tee - 使用tee重定向的write(vim:w)命令的输出。 %只是当前文件名,即/etc/apache2/conf.d/mediawiki.conf。 换句话说,tee命令以root身份运行,它接受标准输入并将其写入由%表示的文件。 但是,这将提示再次重新加载文件(点击L加载vim本身的更改):

教程链接


#6楼

:w !sudo tee % ...

%表示“当前文件”

正如eugene指出的 , %确实意味着“当前文件名”。 Vim中的另一个用途是替换命令。 例如, :%s/foo/bar表示“ 在当前文件中 ,用bar替换foo出现次数”。 如果在键入:s之前突出显示某些文本,您会看到突出显示的行代替%作为替换范围。

:w没有更新您的文件

这个技巧的一个令人困惑的部分是你可能会想:w正在修改你的文件,但事实并非如此。 如果您打开并修改了file1.txt ,则运行:w file2.txt ,它将是“另存为”; file1.txt不会被修改,但当前缓冲区内容将被发送到file2.txt

您可以替换shell命令来接收缓冲区内容 ,而不是file2.txt 。 例如, :w !cat将只显示内容。

如果Vim没有运行sudo访问,它的:w不能修改受保护的文件,但是如果它将缓冲区内容传递给shell,shell中的命令可以用sudo运行 。 在这种情况下,我们使用tee

了解发球台

至于tee ,在正常的bash管道情况下将tee命令描绘成T形管道:它将输出定向到指定的文件, 并将其发送到标准输出 ,可以通过下一个管道命令捕获。

例如,在ps -ax | tee processes.txt | grep 'foo' ps -ax | tee processes.txt | grep 'foo' ps -ax | tee processes.txt | grep 'foo' ,进程列表将被写入文本文件传递给grep

     +-----------+    tee     +------------+|           |  --------  |            || ps -ax    |  --------  | grep 'foo' ||           |     ||     |            |+-----------+     ||     +------------+||   +---------------+|               || processes.txt ||               |+---------------+

(使用Asciiflow创建的图表 。)

有关详细信息,请参阅tee手册页 。

发球作为一个黑客

在你的问题所描述的情况下, 使用tee是一种黑客攻击,因为我们忽略了它的一半sudo tee写入我们的文件并将缓冲区内容发送到标准输出,但我们忽略标准输出 。 在这种情况下,我们不需要将任何内容传递给另一个管道命令; 我们只是使用tee作为编写文件的替代方式,以便我们可以使用sudo调用它。

让这个技巧变得容易

你可以将它添加到.vimrc以使这个技巧易于使用:只需输入:w!!

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

> /dev/null部分显式抛弃标准输出,因为正如我所说,我们不需要将任何内容传递给另一个管道命令。

vim“用sudo写”技巧如何工作?相关推荐

  1. 1-3-linux下vim使用快捷键操作以及解决工作中问题的技巧

    一.vim 安装 [root@pan-T ~]# rpm -qf `which vim` #查看vim命令的安装包 vim-enhanced-7.2.411-1.8.el6.x86_64 [root@ ...

  2. 【Linux】三、Linux 环境基础及开发工具使用(上篇)|开发工具|编辑器-vim使用|sudo提升权限问题|编译器 - gcc/g++使用|项目自动化构建工构建工具-make/Makefile

    目录 一.开发工具 二.Linux编辑器 - vim使用 2.1 vim 的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2. ...

  3. 用Vim编程——配置与技巧

    本文介绍如何用强大的文本编辑器 Vim编程.只要配置得当,效果堪比一个IDE. 配置 基本配置: "开启语法高亮 syntax on "依文件类型设置自动缩进 filetype i ...

  4. 精华转贴:只是为了记录---我们实验室一个牛人去年写的找工作的总结

    精华转贴:只是为了记录---我们实验室一个牛人去年写的找工作的总结 精华转贴:只是为了记录---我们实验室一个牛人去年写的找工作的总结2008-01-28       15:30最近由于某些原因,不能 ...

  5. 写给即将工作和刚刚工作的人们

    写给即将工作和刚刚工作的人们(一)----------hawkpku 时光总是在不知不觉中流逝.转眼又是过了一年.  春季总是容易让人想起过去,即便今年的春季过于炎热,  我甚至开始怀念起非典时的那段 ...

  6. 如何走好人生的第一个五年--写给即将工作和刚刚工作的人

    偶然在未名站读到的帖子,其实是一个系列,我在BBS上只找到了后面的两篇,昨晚躺在床上当做睡前读物,结果阅读越兴奋,睡醒第一件事就是把它分享出来. 不可否认,和社会BBS上的经验文相比,名校BBS上学长 ...

  7. 每天写的叫工作日志,每周写的总结叫周报,每月写的叫月报

    有些时候,老板会突发让您求每天都要写工作周报,什么项目什么任务,完成情况,完成花费的时间等,然后汇总部门周报:也不是写不出,只是不知道有时候重复做一个项目,到底每天有什么好写?不知道大家公司是否写周报 ...

  8. 离职交接文档_如何写好离职工作交接文档?

    交接文档的重要性 一个业务员与客户建立起了私下的信赖关系,可是当他因工作调动而离开原岗位,由另一个人接替的时候,原来的关系很可能就会一下子断裂. 百货商店也一样,如果柜台的营业员换人了,有些顾客就不会 ...

  9. vim编辑器的常用技巧

    vim编辑器的常用技巧 文章目录 vim编辑器的常用技巧 前言 Vi的使用 vi的三种模式 常用按键说明 Vim额外功能 多文件编辑 多窗口编辑 参考文章 前言 我们在使用 Windows 系统时,如 ...

最新文章

  1. 分享几个可以放在博客里的小工具
  2. blade企业级开发平台
  3. Hive分析窗口函数(一) SUM,AVG,MIN,MAX
  4. java中employee_java Employee(雇员)
  5. C#的类修饰符和成员修饰符
  6. Java并发编程实战————售票问题
  7. java8泛型包括_JAVA8 获取泛型类型问题
  8. Solidity 中 revert(), assert() 和 require() 的使用方法
  9. hibernate......1、2级缓存
  10. 入职后发现公司有这5种情况,别留恋,果断离职
  11. R语言在大气污染数据分析中的应用-时间序列分析(一)
  12. Centos 6.5安装python3.5.1
  13. 数据访问组件SqlHelper
  14. unicode编码对照表
  15. The overload Pattern
  16. ArrayList 和 Vector 的区别是什么?
  17. 微信群满100人后无法扫码进群?你们要的解决方法来了!
  18. unity3d音频系统
  19. C++ 修改注册表的方法
  20. 如何让Ubuntu系统支持LDAC,APTX,AAC编码(提升蓝牙音质)

热门文章

  1. 网站后台输入密码错误
  2. ubuntu 常用指令
  3. 18位身份证验证(Java)
  4. 用闭包方式实现点击a标签弹也索引值
  5. 一步一步安装Git控件版本工具
  6. 一次Mysql服务不断重启排查,原因竟然是它
  7. 概率论与数理统计(二)选择题
  8. 10个Python进行数据分析的小技巧
  9. Ecliplse安装tomcat插件
  10. 关于IT测试中的一些问题。