我知道我可以在 bash 中运行最后一个命令!!,但如何运行最后一行输出?
我在考虑这个输出的用例:
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Run Code Online (Sandbox Code Playgroud)
但我不知道我怎么能运行它。我在想类似的东西!!,也许@@或类似的?
hee*_*ayl 21
该命令$(!! |& tail -1)应该执行以下操作:
$ git something
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
$ $(!! |& tail -1)
$(git something |& tail -1)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
git-man liberror-perl
Run Code Online (Sandbox Code Playgroud)
如您所见,sudo apt-get install git命令正在运行。
编辑:分解$(!! |& tail -1)
$()是bash命令替换模式
bash将扩展!!到最后执行的命令
|&部分很棘手。通常 pipe|将采用左侧命令的 STDOUT 并将其作为 STDIN 传递给右侧的命令|,在您的情况下,前一个命令将其输出作为错误消息打印在 STDERR 上。因此,这样做|无济于事,我们需要将 STDOUT 和 STDERR(或仅 STDERR)传递给右侧命令。|&将 STDOUT 和 STDERR 都作为 STDIN 传递给右侧命令。或者,更好的是您只能通过 STDERR:
$(!! 2>&1 >/dev/null | tail -1)
Run Code Online (Sandbox Code Playgroud)tail -1像往常一样将打印其输入的最后一行。在这里,您可以更精确地打印包含apt-get install命令的行,而不是打印最后一行:
$(!! 2>&1 >/dev/null | grep 'apt-get install')
Run Code Online (Sandbox Code Playgroud)特尔;博士: alias @@='$($(fc -ln -1) |& tail -1)'
Bash 的历史交互工具不提供任何机制来检查命令的输出。shell 不存储那个,历史扩展专门用于您自己运行的命令或这些命令的一部分。
这留下了重新运行最后一个命令并将stdout和stderr ( |&)管道化到命令替换中的方法。heemayl 的回答实现了这一点,但不能在别名中使用,因为 shell 在扩展别名之前而不是之后执行历史扩展。
我也无法让历史扩展在 shell 函数中工作,即使在带有set -H. 我怀疑!!在一个函数中永远不会被扩展,我不确定它会被扩展成什么,但现在我不确定为什么不是。
因此,如果您想设置一些东西以便只需很少的输入就可以做到这一点,您应该使用fcshell 内置而不是历史扩展来从历史中提取最后一个命令。这还有一个额外的优势,即使历史扩展被禁用,它也能工作。
如戈登戴维森对创建包含 bash 历史扩展的别名(在超级用户上)的回答所示,模拟. 在heemayl 的命令中插入它会产生:$(fc -ln -1)!!!! $(!! |& tail -1)
$($(fc -ln -1) |& tail -1)
Run Code Online (Sandbox Code Playgroud)
这就像$(!! |& tail -1)但可以进入别名定义:
alias @@='$($(fc -ln -1) |& tail -1)'
Run Code Online (Sandbox Code Playgroud)
在您运行该定义,或将其放入.bash_aliases或.bashrc启动一个新的 shell 之后,您可以简单地键入@@(或任何您命名的别名)来尝试执行最后一个命令的最后一行输出。
ek@Io:~$ alias @@='$($(fc -ln -1) |& tail -1)'
ek@Io:~$ evolution
The program 'evolution' is currently not installed. You can install it by typing:
sudo apt-get install evolution
ek@Io:~$ @@
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
evolution-common evolution-data-server evolution-data-server-online-accounts
....Run Code Online (Sandbox Code Playgroud)