Why does echo !() print the contents of the current directory?

I have been teaching myself the meaning of various bash ‘reserved words’.

In doing this, I inadvertently typed the command

echo !()

To my surprise, this command executes, and produces output identical to the command

echo *

In other words, the output was a list of the contents of the current directory

file1 file2 directory1 directory2

Why is bash essentially expanding !() to * ?

I can’t determine the meaning of (), as it seems to be an invalid expression in other contexts.

Asked By: jrt


It’s bash’s extglob pattern matching syntax which it copied from the Korn shell (a subset thereof). !(pattern), when the extglob has been enabled one way or another (like via the bash_completion add-on in interactive shells) expands to the names of the (non-hidden by default) files in the current working directory that don’t match pattern.

With an empty pattern, that’s all files in the current directory whose name is not the empty string, but a file name cannot be empty anyway so that’s all the (non-hidden by default) files.

You’ll get the same in zsh with echo ^ when its extendedglob option is enabled where ^pattern is its equivalent of ksh’s !(pattern).

Answered By: Shawn
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.