I took a closer look on this phenomenon after I stumbled over it in two other questions today. I've tried all of this with the default set -H (history expansion on).

To test a script, I often do things like echoing a multi-line string and pipe it through a script, but in some cases it gives an error:

$ echo "foo
bar" | sed '/foo/!d'
bash: !d': event not found

The ! seems to trigger history expansion, although it is enclosed with single quotes. The problem seems to be the occurrence of the double quote in the same line, because

$echo $'foo\nbar' | sed '/foo/!d'

works as well as

$echo "foo
bar" |
> sed '/foo/!d'

My suspicion: History expansion is applied linewise, so the ' after a single " is considered to be escaped, so the following ! is not escaped.

Now my question: Is this a bug or expected behavior? Reproduced with bash versions 4.2.30 and 4.4.12.

  • 1
    Just tried with zsh (history expansion on): No such problem. Really seems to be a bug in bash
    – Philippos
    Sep 8, 2017 at 7:54
  • 1
    The problem is poor implementation of history expansion in bash. You can disable the whole implementation by adding set +H to .bashrc. In that case, bash never attempts to do any history expansion stuff anywhere (that is, behave like proper bourne shell) and you'll have less nasty surprises. Nov 14, 2018 at 7:41

1 Answer 1


I reported this to [email protected] and got this answer:

History expansion is explicitly line-oriented, and always has been. There's not a clean way to make it aware of the shell's current quoting state (mostly since it's a library independent of the shell). Maybe there's a way to use one of the existing callback functions to do it.

This sounds to me like "this is not a bug, because we can't do it any better with the current implementation".


I lost interest in this subject after switching to zsh. Now I tried with bash version 5.1.4 and found the problem can't be reproduced anymore. So somewhere between 4.4.12 and 5.1.4, somebody did fix this.

  • 3
    "we can't do it any better with the current implementation" sounds like an implementation bug for me. Nov 9, 2018 at 11:20
  • I can reproduce the bug in v4.4.18, but not in v5.0.0, so it's probably v5 that fixed it. Mar 17, 2022 at 17:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .