【问题标题】:What's the use of `!#` in bash?bash 中的 `!#` 有什么用?
【发布时间】:2018-01-24 23:58:30
【问题描述】:

我不是在谈论旨在提供解释器路径的 UNIX shebang。事实上,shebang 已经很难在 google 上成功地搜索到这个问题了......

我说的是bash扩展:

  • !! 检索前面的命令(类似于向上箭头,但更有用)
  • !$ 检索最后一个命令的最后一个单词
  • !# 似乎检索当前行

但是!# 的实际用途是什么?

  • echo !# 扩展为 echo echo
  • echo echo !# 扩展为 echo echo echo echo
  • ls !# 扩展为 ls ls

所有这些似乎都毫无意义。关于!# 命令,我所知道的只是我从使用它中学到的东西——我不确定我是否知道它的真正功能。

【问题讨论】:

  • 记录在案here;它扩展为“到目前为止键入的整个命令行。”。
  • man bash | grep '!#'
  • 您有两个答案给出了定义,但是您是否正在寻找 !# 的有效使用示例?
  • @WillBarnwell 是的!我是。我真的有两个问题。 1)这个有什么用。 2)我看不到这个的用途......这真的是!#所做的一切吗? –– 问题 2 得到了很好的回答:“是的。事实上,这就是 !# 所做的一切。” 然而,这让我更想知道问题1的答案!
  • @AriSweedler, ...历史扩展是为了向后兼容我们有 readline 之前的时间而存在的,并且为了那个时代仍然有手指记忆的人们的利益。关闭它(使用set +H)通常被认为是个好主意。

标签: bash shell


【解决方案1】:

正如问题和其他答案中提到的cmets,您可以轻松找到man bash的部分:

!#     The entire command line typed so far.

手册页或其他文档没有明确说明并且可能会导致您对!# 的有用用途感到困惑的是 bash 事件指示符旨在与单词指示符和修饰符结合使用(找到就在手册页上的事件指示符下方)。当将命令与管道链接在一起时,用例也更有意义,;&/&&

例如:

我可以使用替换修饰符针对两个输入 barbaz 运行脚本 foo.sh

$ ./foo.sh bar; !#:s/bar/baz/

展开为:

./foo.sh bar; ./foo.sh baz;

或者下面复制的 Docs (R.I.P. Docs) 中的示例显示了如何使用单词选择器 :N 来选择迄今为止键入的命令的第一个参数,并整齐地 cd 到刚刚创建的目录中:

$ mkdir backup_download_directory && cd !#:1
mkdir backup_download_directory && cd backup_download_directory

这些示例非常琐碎,但我希望它们能够展示 !# 如何真正为人们节省一些严重的冗余输入,同时制作强大的单行代码。

【讨论】:

  • 啊,我明白了。 !# 是一个不完整的工具!这是没有刀片的剪刀的手柄。在阅读了9.3.29.3.3 之后,有人将!# 编码为存在的面孔更有意义。感谢@KeithThompson 在9.3.1 中的链接,这些是我需要的参考指南。 @WillBarnwell,感谢您的完整回答!
【解决方案2】:

!#到目前为止键入的整个命令行。来自man bash

Event Designators
   An event designator is a reference to a command line entry in the history list.

   !      Start a history substitution, except when followed by a blank, newline, carriage return,  =  or  (
          (when the extglob shell option is enabled using the shopt builtin).
   !n     Refer to command line n.
   !-n    Refer to the current command line minus n.
   !!     Refer to the previous command.  This is a synonym for `!-1'.
   !string
          Refer to the most recent command starting with string.
   !?string[?]
          Refer  to  the  most recent command containing string.  The trailing ? may be omitted if string is
          followed immediately by a newline.
   ^string1^string2^
          Quick substitution.  Repeat the last command,  replacing  string1  with  string2.   Equivalent  to
          ``!!:s/string1/string2/'' (see Modifiers below).
   !#     The entire command line typed so far.

使用示例:

$ mkdir foo && cd !#:1

创建目录foo 并对其进行更改。

【讨论】:

  • 太棒了!我提到了我如何在 cmets 中对我最初的问题提出两个问题,但这回答了我的第三个问题:“其他 !* 命令是什么,它们是做什么的?我在哪里可以找到他们的文档?”我应该知道它会在手册页中。它们被称为“事件指示符”。谢谢! :)
  • @AriSweedler,我添加了一个用法示例。
猜你喜欢
  • 1970-01-01
  • 2011-10-24
  • 2014-09-07
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多