了解 bash 中的感叹号 (!)

Vas*_*ass 129 command-line bash command-history

我用了

history | less
Run Code Online (Sandbox Code Playgroud)

为了获取先前命令的行和左侧的数字,我找到了我想要重复的行(例如 22)并做了

!22
Run Code Online (Sandbox Code Playgroud)

在命令提示符下,它起作用了——在我当时所做的行上执行命令集。我无法弄清楚感叹号在哪里使用,它在 bash 采取的操作方面代表什么,以及在哪里使用它。从文档中我没有看到“有形”的解释。

War*_*ung 181

!调用历史扩展,这是一个最初出现在C shell 中的功能,早在您可以指望终端具有箭头键之前的日子。如果您将当前命令编号添加到提示 ( PS1="\!$ ") 中,这将特别有用,这样您就可以快速查看屏幕以获取过去命令的编号。

既然您可以使用箭头键和诸如Ctrl-R搜索命令历史记录之类的东西,我认为该功能没有多大用处。

您可能仍然觉得有用的一个变体是!!,它重新执行上一个命令。就其本身而言,我没有发现!!Enter任何比 更快的方法? Enter,但是当组合成一个更大的命令时它会很有帮助。

例如:一个共同的导频误差sudo为基础的系统是忘记sudo上需要额外的特权的指令前缀。新手重新输入整个命令。勤奋的学生从 shell 的命令历史中编辑命令。开明的一种sudo !!

!以这种方式处理在 Bash 中默认在交互式 shell 中启用,并且可以使用set +o histexpand或禁用set +H。您可以在 Zsh 中使用set -K.

  • 如果你只想运行最后一个命令,Up/Enter 没问题,但如果你想以某种方式添加它(比如,你忘记了 `sudo` 或其他东西),那么你可以执行 `sudo !!` , 例如。这可能比“Up/Ctrl-A(或 Home,如果你足够幸运)/sudo/space/enter”快一点。天啊。:) (29认同)
  • 我发现 Ctrl-P Ctrl-J 非常快;至少比 Up Enter 快。 (5认同)
  • 对“开明者”的赞美:) 不敢相信我一直只是一个勤奋的学生...... (3认同)
  • 值得一提的是,如果您在“!”和命令之间留有空格,您将否定其退出代码(布尔“not”运算符)。 (3认同)

Cry*_*vok 60

如果这里没有更长的答案,那么肯定有一个关于超级用户的答案,因为我最近读过一个。在bash 手册页中,您可以找到一个很大的部分,标题为HISTORY EXPANSION

您可以执行整个主机的操作,而不仅仅是运行最后一个命令或命令编号 X。您可以执行诸如!cat运行以cat. 或者!?bash?:s/bash/csh/运行包含bash但替换为的最后一个命令csh

  • 虽然不是直接回答 OP 的问题,但这需要更多的支持。太有用了!谢谢,哈沃克。 (4认同)
  • `!!:s/bash/csh/` 实际上运行 *last 命令*,然后用 csh 替换 bash(如果存在)。不是最后一个包含 bash 的命令。那将是 `!?bash?:s/bash/csh/` 或者可能是 `!?bash?:s/%/csh/` (2认同)

use*_*997 49

可以做更多的事情,!例如:

  • 执行在 3 个命令之前键入的命令: !-3
  • 执行以开头的命令 !ls

还有很多。查看您应该知道的 15 个 Linux Bash 历史扩展示例


Tes*_*a J 8

当然,您可以!!在 bash shell 中重用最后一个命令。然后是!$重用上一个命令的最后一部分。

例如查看一些文件

less path/to/your/file.txt
Run Code Online (Sandbox Code Playgroud)

如果您现在想编辑同一个文件,您可以使用!$仅从最后一个命令中获取文件路径

vim !$
Run Code Online (Sandbox Code Playgroud)

编辑:

您可以使用上一个命令的所有参数 !*

例如:这将创建一些文件并删除所有文件

$ touch a.txt b.txt c.txt d.txt
$ rm !*
Run Code Online (Sandbox Code Playgroud)

同样,您可以使用上一个命令的特定参数

例如,这将创建 4 个文件并将删除第三个文件 (c.txt)

$ touch a.txt b.txt c.txt d.txt
$ rm !:3
Run Code Online (Sandbox Code Playgroud)

同样,您可以使用上一个命令中的一系列参数,如下所示

$ touch a.txt b.txt c.txt d.txt
$ rm !:2-4
Run Code Online (Sandbox Code Playgroud)

这将重用参数 2 到 4 来计算表达式 rm b.txt c.txt d.txt

  • 啊,我希望找到这个。它如何处理两个 args? (2认同)

Vas*_*ass 6

我的一个朋友给我发了这样的电子邮件:

它是 GNU 历史库的一部分。在 bash 中,它用于重新运行历史记录中的命令。如果你想成为硬核,请在 bash-4.1/lib/readline/histexpand.c 中 grep for History_expansion_char 以获取实现细节。