使用“sudo”重复上一个命令

81

我经常忘记用sudo运行命令。我正在寻找一种方法来创建一个bash函数(或别名),以便重复上一个带有sudo的命令。类似于:

S() {
    sudo $(history 1)
}

有什么想法吗?


别名需要额外的工作:http://superuser.com/questions/240180/creating-an-alias-containing-bash-history-expansion - Ciro Santilli OurBigBook.com
5
如果你不介意脏话的话,有一个叫做 thefuck 的软件包:https://github.com/nvbn/thefuck。它会尝试找出之前命令无法工作的任何原因并让其运行(例如使用sudo)。只需输入 fuck 即可。 - slebetman
5个回答

154

你可以写:

sudo !!

(请参见Bash参考手册中的§9.3“历史记录扩展”。)


26

还不够?

sudo !!

如果您想要 S,只需简单地执行以下操作:

alias S=sudo

并使用它

S !!

!! 表示上一个命令


5
不错。我的用途是将精心制作的命令行立即转换为脚本: echo !! > script.sh - FractalSpace
1
或者使用 alias S='sudo $(history -p !!)',然后只需输入 S - Aaron Franke

22

使用 alias redo='sudo $(history -p !!)'。这是我找到的唯一适用于别名的方法。其他答案在别名中不起作用,尽管它们在直接运行时起作用。


1
由于某种原因,我不得不使用eval alias r='eval sudo $(history -p !!)' - alchemy

16

!! 可用于引用最近一条命令,例如:

sudo !!

12

Aaron Franke的回答基础上添加和扩展(回答是正确的,但缺乏一个为什么),这样只需输入redo就可以在配置别名alias redo='sudo $(history -p !!)后正常工作;

这是我发现与别名一起使用的唯一可行方法。

有几件事情需要解释。

alias redo='sudo !!'

由于它不执行sudo部分,因此它无法正常工作,尽管它可以解决!!

为了使sudo !!正确解析,必须执行一个shell解析指令并与sudo连接。所以我们这样做:

alias redo='sudo $(history -p !!)'

通过指定别名的右侧为$(history -p !!),这样做的目的是告诉shell:
  1. redo是一个别名,评估=的右侧
  2. sudo保持不变,并连接到...
  3. $()是一个shell指令,用于在当前执行过程中执行内容(与子shell ${}相反,后者会生成不同的进程来执行)
  4. 解析history -p !!
  5. 由于步骤4的结果,!!被扩展为history -p <lastCommandHere>
  6. -p部分表示只打印结果,而不执行history
  7. sudo使用提升的特权执行剩余部分(现在在同一命令行上打印出来),假设密码已正确输入
这最终意味着命令history -p !!有效地写出了解决方案,而不是在sudo之后执行。

注意:单引号'是有意义的。如果使用双引号"!!会被解析两次,为了达到我们的目的,我们需要非常小心地控制解析步骤;bash中的单引号和双引号

附言

如果您正在使用zsh+oh-my-zsh,则设置了一个sudo别名,以便您可以执行以下操作:

_ !!

这将以sudo重新运行上一个命令。然而,如果您正在~/.zshrc中配置别名,则alias redo='sudo $(history -p !!)将无法像从zsh配置中那样工作,因为解析步骤不同。

话虽如此,您可以将别名放入~/.bashrc而不是~/.zshrc,并在从zsh执行别名redo时获得相同的结果(假设您从bash子shell zsh,尽管这有点笨拙-但是功能性的)。


2
“zsh”的技巧值得一试 :) - user5395338

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