在脚本和别名中使用 bash 的 bang 命令(例如‘!!’)?

在脚本和别名中使用 bash 的 bang 命令(例如‘!!’)?

是否可以在 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

相关内容