Escaping Exclamation Marks in Bash

If you’ve ever committed to Git in either frustration or excitement, you’ve probably seen a message like this:

1
2
$ git commit -m "It works!"
-bash: !": event not found

When Bash encounters an exclamation mark under certain conditions, it tries to expand the expression to the last matching command in your history. For example:

1
2
3
4
5
6
7
8
9
10
$ echo "Hello, World"
Hello, World
$ ls
bin  foo.sh
$ !e
echo "Hello, World"
Hello, World
$ !l
ls
bin  foo.sh

Notice that the second command !e was expanded to the previous echo "Hello, World" statement, and !l is expanded to the previous ls statement. This is cool, but can also be annoying if that’s not what you want. Fortunately there’s a workaround.

1
2
3
4
5
6
7
8
9
# If you don't need variable substitution, use single quotes
$ git commit -m 'It works!'

# If you need variable substitution, keep exclamation outside the quotes
$ git commit -m "Thanks $name"\!
# Or escape with single quotes
$ git commit -m "Thanks $name"'!'
# Also works in the middle of the line
$ git commit -m "Thanks"\!" $name"

As far as I can tell, these solutions work in both Linux, and Git Bash in Windows.

You can also work around this by leaving of the -m and editing your commit message in vim like a real developer

A couple pages I found helpful when figuring this out:

I am now accepting new clients for part-time consulting and software development projects. Learn more

I haven't configured comments for this blog, but if you want to get in touch, you can find me on Twitter