When I am searching for a file with

ls [a-t]est.txt

it gives the result test.txt as expected

However, when I use

ls [!a-g]est.txt

output is ls [aptg]est.txt

Some other examples for [!set]:

  • ls [!b-z]est.txt returns [bbz]est.txt
  • ls [!g-h]est.txt returns ls [git clone --depth=1h]est.txt

Is there something wrong with my zsh, or does [!set] works differently in zsh?

Machine is Linux Mint 18.2

  • 2
    Try ^ in place of ! for negation - it looks like ! is invoking a command history expansion (at least in the interactive shell) Jul 19, 2017 at 1:56
  • Yes! That is it. Do you know why ! is (by the looks) invoking a command history expansion? And how do you know how to restore this?
    – urben
    Jul 19, 2017 at 2:01
  • 2

2 Answers 2


As proposed by steeldriver, ^ in place of ! makes [!set] resolves the issue.

Reason for this is that in zsh ! triggers the history expansion. If you do not want this to happen, disable the history expansion. For this, execute setopt nobanghist in the command line.


One way to avoid history expansion is to quote ! a backslash:

ls [\!a-g]est.txt

Of course when negating a set it is probably easier to just use ^ instead of !.

Another way is to temporarily disable history expansion by adding the character sequence !" anywhere (really!) before the (previously) first !. !" will be removed and any subsequent ! have no special meaning.

!" ls [!a-g]est.txt
ls !" [!a-g]est.txt
ls [!"!a-g]est.txt
l!"s [!a-g]est.txt

You must log in to answer this question.

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