If you are a Linux command-line user, most likely, you are familiar with the use of the single asterisk ('*') in pathname expansion (aka globbing). How the asterisk behaves is standardized across all shells (
tcsh, etc). For example, the
ls * command lists the files and the immediate sub-directories of the current directory.
$ ls *
The single asterisk, however, is not recursive: it does not traverse beyond the target directory. You may use the
find command to generate a recursive listing of pathnames. A simpler solution is the use of the double asterisk ('**').
Unlike the single asterisk, the double asterisk is not standardized. Different shells introduced the feature at different times with slightly different behavior. This post focuses on the use of '**' for the
The double asterisk feature for
bash first appears with
bash4. To find out which
bash version you are running, execute the following command:
$ bash --version
GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
Before you use '**', you must first enable the
globstar shell option:
$ shopt -s globstar
globstar enabled, you may use '**' for pathname expansion.
$ ls **/abc.txt
In the above example, the
ls command returns any occurrence of the file
abc.txt in the current directory and sub-directories.
By default, the double asterisk does not expand to include a hidden file. For example, the following command will not find
.htaccessbecause it is a hidden file.
$ ls **/.htaccess
To allow hidden files in '**' output, enable the
$ shopt -s dotglob
When you do a pathname expansion using '*' or '**', you run the risk that a returned filename is the same as a command-line flag, e.g.,
-r. To mitigate that risk, precede '**' with '--' as below. The double dash marks the spot where command-line flags end, and positional parameters begin.
$ ls -- **
bash, '**' expands to follow symbolic links. This behavior, however, is shell-specific. For
zsh, expanding the double asterisk does not follow a symbolic link.
The double dash is a useful tool to add to your everyday command-line usage.