gpt4 book ai didi

zsh - 访问 Zsh 中的最后一个命令(不是上一个命令行)

转载 作者:行者123 更新时间:2023-12-04 15:22:23 24 4
gpt4 key购买 nike

有没有办法在 Zsh 中检索最后一个命令的文本?我的意思是最后执行的命令,而不是最后一个命令行。

尝试了什么

尝试这样做时,我发现了 Zsh 和 Bash 处理历史的细微差别。这种差异在以下示例中得到了体现,这是我在 Bash 中所做的工作的基础,在 Zsh 中不起作用。

$ zsh
$ echo "This is command #1"
> This is command #1
$ echo "This is command #2"; echo $(history | tail -n1)
> This is command #2
> 3807 echo "This is command #1"

$ bash
$ echo "This is command #1"
> This is command #1
$ echo "This is command #2"; echo $(history | tail -n1)
> This is command #2
> 4970 echo "This is command #2"; echo $(history | tail -n1)

相同的测试,其结果在最后一行有所不同。 Bash 在执行前将命令行附加到历史记录中(我不知道是不是按规范),而 Zsh 似乎在执行后将命令行附加到历史记录中(相同,我不知道是不是按规范) ),因此 history | tail -n1不给一样。

我想要的是能够检索 echo "This is command #2" ,即上一个命令的文本,即使它与其他命令在同一命令行上(当多个命令以 ; 分隔时)。

使用 bash,我可以使用 history | tail -n1 | sed ... ,但是由于历史处理的差异,这对 Zsh 不再适用。

需要达到什么

关于如何从 Zsh 中的多命令命令行获取最后一个命令的任何想法?

当一个命令需要知道上一个命令是什么时,我需要它,无论该命令是在同一行还是上一行。另一种说法可能是:我需要访问单个面向命令的历史记录的最后一项,而不是面向命令行的历史记录的最后一项。

最佳答案

据我所知,在 zsh 中没有简单的方法。我相信在交互式 shell 中最接近您问题的答案是使用历史扩展机制,尤其是 !# ,但您可能对 !! 感兴趣, !!:1和其他人也是如此。从 zsh 手册:

!# Refer to the current command line typed in so far.



因此,您可以执行以下操作来获取上一个命令:
echo "This is command #1"; var=$(echo !#) && echo "The previous command was:" \'$var\'

结果是
This is command #1
The previous command was: 'echo This is command #1'

你也可以玩
echo "This is command 1"; var=$(echo "!#:s/;//") && echo "The previous command was:" \'$var\'

如果您需要附上 !#带双引号,但在这种情况下,您必须删除 ;从“最后一条命令”的末尾开始。 :s/;//正在这样做。更复杂的命令现在运行良好:
ls >/dev/null 2>&1; var=$(echo "!#:s/;//") && print "The previous command was:" \'$var\'

给出输出:
ls >/dev/null 2>&1; var=$(echo "ls >/dev/null 2>&1") && print "The previous command was:" $var
The previous command was: 'ls >/dev/null 2>&1'

但是请注意,在这种情况下 #不应与引号一起出现在第一个命令中,因为它将被解释为注释。

注释 1

重要的是 !#表示到目前为止当前行中存在的所有内容,除了当前原子,因此 var在表达式中
echo "This is command #1"; var=$(echo !#) && echo "The previous command was:" \'$var\'

实际上等于:
var=$(echo echo "This is command #1";)

以便 echo $var版画 echo This is command #1正如先前所说。
但是如果我们写简化版,没有变量:
echo "This is command #1"; echo "The previous command was:" !#

然后 !#将包含额外的,第二个 echo及其参数,因此实际上命令将变为:

echo "This is command #1"; echo "The previous command was:" echo "This is command #1"; echo "The previous command was:"



注释 2

这个解决方案显然并不完美,因为您可能已经注意到,引号没有包含在变量中。您可以尝试通过在 !# 周围附加单引号来解决它但不是直接的(否则历史扩展将不起作用)。

注释 3

如果一行中有超过 3 个或更多的命令,用 ; 分隔, 而不是您需要更多地使用 zsh 修饰符或使用 sed 或 awk 等外部命令。

关于zsh - 访问 Zsh 中的最后一个命令(不是上一个命令行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25295186/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com