今天在另外两个问题中偶然发现这个现象后,我仔细研究了这个现象。我已经在默认情况下尝试了所有这些set -H
(历史扩展打开)。
为了测试脚本,我经常做一些事情,例如echo
ing 多行字符串并将其通过脚本进行管道传输,但在某些情况下会出现错误:
$ echo "foo
bar" | sed '/foo/!d'
bash: !d': event not found
>
!
尽管用单引号括起来,但似乎会触发历史扩展。问题似乎是在同一行中出现双引号,因为
$echo $'foo\nbar' | sed '/foo/!d'
效果也很好
$echo "foo
bar" |
> sed '/foo/!d'
我的怀疑:历史扩展是按行应用的,所以'
后面的单个"
被认为是转义的,所以下面的!
没有转义。
现在我的问题是:这是一个错误还是预期的行为?复制bash
版本为 4.2.30 和 4.4.12。
答案1
我将此报告给[email protected]
并得到了这个回答:
历史的扩展显然是以路线为导向的,而且一直如此。没有一种干净的方法可以让它了解 shell 的当前引用状态(主要是因为它是一个独立于 shell 的库)。也许有一种方法可以使用现有的回调函数之一来完成此操作。
这对我来说听起来就像“这不是一个错误,因为我们无法用当前的实现做得更好”。
更新
转行后我对这个话题失去了兴趣zsh
。现在我尝试使用bash
5.1.4版本,发现问题无法再重现。所以在 4.4.12 和 5.1.4 之间,有人确实修复了这个问题。