Double asterisk brings double expedience to pathname expansion


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 (bash, zsh, 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 bash shell.
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
With 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.
Notes:
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 **/.htaccessTo allow hidden files in '**' output, enable the
dotglobshell option:
$ shopt -s dotglobWhen 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 -- **Under
bash, '**' expands to follow symbolic links. This behavior, however, is shell-specific. Forzsh, 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.