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.
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)
.