I have this directory structure:

~/tmp/globstar ɀ  find dir -type f

and, with the globstar option enabled in Bash, I can say:

~/tmp/globstar ɀ  ls -1 dir/**/*.ext

My question is: why is dir/file.ext excluded from this list?

Bash manual says this about globstar:

If set, the pattern ‘**’ used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a ‘/’, only directories and subdirectories match.

zero” in this paragraph let me with the impression that dir/file.ext should have been included; unless I’m hopefully missing something.

  • 2
    What is this character? ɀ? – slm Mar 2 '14 at 23:17
  • 2
    What version of bash, on what platform? I can't reproduce this with bash 4.2.37 on Debian wheezy or bash 4.1.5 on Debian squeeze. @slm unicode ɀ or Wikipedia – Gilles 'SO- stop being evil' Mar 2 '14 at 23:32
  • 1
    @Gilles Is that a prompt? – slm Mar 2 '14 at 23:41
  • 5
    slm, Yes! ɀ is just a character used here to distinguish prompt. Some users prefer the character £ or instead of $ :). Originally, ɀ a 'z' character created for a special African language notation :-) – Slyx Mar 3 '14 at 0:51
  • 1
    "GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13)" shipped with OS X 10.9 has this behavior. – natevw Mar 31 '15 at 21:23

I guess that refers to the subdirectory level only. ** without / matches

  1. all files and directories

  2. zero or more subdirectories

But it does not completely disappear. **/ means that no files in the highest-level directory which ** applies to are matched.

You need dir/*.ext dir/**/*.ext.

  • Yeah, that’s exactly my fallback, it just doesn’t look pretty. ;-) – Vlad GURDIGA Mar 3 '14 at 11:56

This works as you expected in these versions of Bash as supplied with the listed distributions:

  • 4.1.2(1) — CentOS 6.5
  • 4.1.5(1) — Debian 6.0.10
  • 4.1.10(4) — Cygwin 1.7.31
  • 4.2.46(1) — CentOS 7.1
  • 4.3.11(1) — Ubuntu 14.04.1
  • 4.3.30(1) — Debian 8.1

In fact the versions listed above are all that I tested. In other words I did not find a version 4 of Bash where it does not work. The option globstar was added in Bash 4.0 see CHANGES. In older versions the command shopt -s globstar should return an error.


1. dir/**/*.ext matches dir/file.ext:

~/tests$ ls -1 dir/**/*.ext

2. **/*.ext matches file.ext:

~/tests$ cd dir
~/tests/dir$ ls -1 **/*.ext

Preparing the environment for reproducing the tests above:

mkdir -p dir/subdir{1,2}
touch dir/{,subdir{1,2}/}file.ext
shopt -s globstar
  • 2
    this is the right answer. The OP forgot to set shopt -s globstar. – CS Pei Dec 15 '17 at 3:14

I looks to me like you have/had globstar turned off. It can be turned on on like this:

shopt -s globstar

Not only will it not match zero subdirectories, but it won't match two subdirectories either:

$ find dir -type f #the same as yours except with a directory inside one of the subdirectories
$ shopt -u globstar #turn globstar off
$ #will only show files in subdirectories
$ #will not show files in dir or in subsubdir
$ echo dir/**/*.ext
dir/subdir1/file.ext dir/subdir2/file.ext
$ shopt -s globstar #turn globstar on
$ #will show all four files
$ echo dir/**/*.ext
dir/file.ext dir/subdir1/file.ext dir/subdir1/subsubdir/file.ext dir/subdir2/file.ext

With globstar off, ** ends up behaving just like *, so dir/**/*.ext gets the same result as dir/*/*.ext

$ echo dir/*/*.ext
dir/subdir1/file.ext dir/subdir2/file.ext

which sometimes tricks me into thinking globstar is on

check your current globstar setting like this:

shopt | grep globstar
  • 1
    You can check a shell option setting directly, as in shopt globstar. – Benjamin W. Sep 4 '18 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.