![我可以让我的 shell 历史记录记录通配符的扩展方式吗?](https://linux22.com/image/1448/%E6%88%91%E5%8F%AF%E4%BB%A5%E8%AE%A9%E6%88%91%E7%9A%84%20shell%20%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95%E8%AE%B0%E5%BD%95%E9%80%9A%E9%85%8D%E7%AC%A6%E7%9A%84%E6%89%A9%E5%B1%95%E6%96%B9%E5%BC%8F%E5%90%97%EF%BC%9F.png)
如果我运行:
$ ls *
foo bar buzz
$ history | tail -1
ls *
您可以看到,在我的 shell 历史记录中,它记住的是我运行ls *
而不是ls foo bar buzz
.理想情况下,我想将两者记录在不同的历史中。当我想知道“文件 foo 到底发生了什么?”时,如果能够rm *
通过搜索历史记录并找到“foo”来返回并找出我在错误的目录中执行的操作,那就太好了。
我对 zsh 和 bash 的解决方案感兴趣。
答案1
我认为在将命令存储到历史记录中时,任何 shell 都不会执行除了空格修改之外的任何操作。扩展的内容*
没有被记录,并且似乎没有记录它的选项。
请注意,无论如何都不可能记录完整的普遍性。例如,如果您运行a='foo* bar*'; rm $a
(rm $=~a
在 zsh 中),shell 不太可能在语法上检测到通配符匹配。并且没有记录所有全局扩展的选项。
你可以将一些东西拼凑在一起preexec
(或者bash 等价物)。未经测试的第一次(对于 zsh):
history_wildcards=()
precmd () {
emulate -LR zsh
local n tmp
history -1 | read n tmp
history_wildcards[$(($n+1))]=$=~1
}
这会将history_wildcards
数组填充为一个字符串,其中包含命令行中每个单词的全局扩展。分词是以简单的方式执行的,因此类似的东西echo ' /**/* '
会扩展/**/*
(即遍历您的磁盘)。不要指望从中得到任何有用的东西cd subdir && echo *
或任何如此令人难以置信的不平凡的东西。
如果您事先计划,您可以在提交命令之前让 zsh 扩展通配符。在默认配置中,只需Tab在光标位于球体上时按下即可。如果您以不同的方式配置完成,请尝试^X *
( expand-word
)。