4

If I run

grep "!" test.txt

it will show error

bash: !: event not found

Well, I know I actually should use grep '!'. But how to understand the above error?

I know ! is bash special character. According to http://mywiki.wooledge.org/Quotes.

Double quotes: "..." prevents some substitutions but allows others. Every substitution that begins with a dollar sign $ is performed, as is the legacy ... (backtick) command substitution. Backslash escaping is also performed. No word splitting or filename expansion is performed.

It doesn't mention that double quotes will affect !. Could somebody explain how does bash or grep interpret grep "!"? What is the "event"?

user15964
  • 713

2 Answers2

6

It's not grep that's causing it. It's your bash that is interpreting the !. Switch to a newer version of bash or use single quotes '!' to shut up bash.

  • why new version has no error? Bug or some new feature? – user15964 Mar 20 '17 at 15:55
  • 1
    Actually in your scenario, grep \! test.txt would work as well. I guess it's a bug that's why this changed behavior. –  Mar 20 '17 at 16:00
  • Ok, grep '!' works, Why bash -c 'grep \'!\' test.txt' doesn't work? – user15964 Mar 20 '17 at 16:05
  • Actually you need to realize how quoting works, single quoting , that is, in your above case. You can't slip in a single quote inside of single quotes just by escaping it. Why? Coz, the backslash ain't special inside of single quotes, the way it is special inside double quotes or in empty space. You shoud do this: bash -c 'grep '\''!'\'' test.txt' –  Mar 20 '17 at 16:21
  • The History Expansion feature is still available and enabled by default as of Bash 4.4.19, and I don't expect it to be removed soon. Quote it or put set +o histexpand in your .bashrc or equivalent. – arielCo Nov 03 '18 at 21:27
3

You're looking at Bash's History Expansion feature. Some find it handy to recall previous commands, but I just put set +o histexpand in my .bashrc and press Ctrl+R to search for part of the command.

arielCo
  • 1,058