是否可以在 bash 脚本和 bash 别名中使用所谓的 bang 命令(!
+ 命令/符号,例如!!
或)?!$:p
我想添加一行
alias getit='sudo apt-get install !!'
到我的~/.bashrc
文件,能够通过getit
在命令本身不成功调用后键入来安装未找到的命令,类似于该工具的行为他妈的,只是少说脏话……
然而,这一行不起作用,如下面的输出所示:
$ cowsay
The application »cowsay« is currently not installed.
You can install it by typing:
sudo apt-get install cowsay
$ getit
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package !!
$
请注意,我自己将第一个命令的输出从德语翻译了出来,但LANG=C
因为种种原因,这个命令没有起到作用。
无论如何,您可以看到别名中的 bang 命令不会被解释为替换为最后执行的命令,而是保持相同的字符串。我已经发现 bang 命令通常仅在交互式 shell 中起作用,因此在脚本中不起作用。
是否可以更改此设置,以便!!
将其解释为脚本中最后执行的命令字符串?别名怎么样,可以吗?
答案1
历史扩展在别名扩展之前完成,因此您必须使用history
内置函数自己执行扩展:
alias getit='sudo apt-get install $(history -p !!)'
但是,上述别名使用整个最后执行的命令作为 的参数sudo apt-get install
,这意味着如果我们为失败的命令提供了一个参数(如cowsay "Hello"
),那么现在这个参数也会出现在要安装的包列表中(sudo apt-get install cowsay "Hello"
)。
由于这不是预期的,我们应该将别名修改为钢铁司机建议使用!:0
而不是!!
仅获取第一个单词(命令名称):
alias getit='sudo apt-get install $(history -p !:0)'
我们仍需注意,此过程仅在失败的命令名称与其软件包名称相同时才有效。例如,它不适用于命令lynx
(CLI 浏览器),因为它包含在软件包中lynx-cur
。