Wildcard expansion

The characters '?' and '*' are treated as wildcards on the command line in both Microsoft Windows and Unix. In both cases the wildcards are expanded by matching against filenames, a process known as 'globbing'. A '?' matches a single character and '*' matches multiple characters.

In Unix wildcards are expanded by the shell and any matching filenames are passed as arguments to the program being run. In Windows the command intepreter passes unexpanded arguments to the program and the C runtime library performs the expansion. In both cases the expansion happens before the main function of the program is executed.

These different mechanisms for globbing result in a difficulty for BusyBox on Windows. BusyBox contains a Unix-style shell, which performs Unix-style globbing on the command line, but busybox.exe is a Windows command line program, which would normally have globbing performed by the C runtime.

When a command is run from the BusyBox shell the shell expands any wildcards. If the command is one of those implemented by BusyBox the busybox.exe binary is executed again. If any wildcards weren't expanded by the shell (either because they failed to match or because they were escaped by the user) they will be passed to this second invocation of BusyBox. If busybox.exe were to expand these wildcards in might result in unexpected behaviour.

To avoid this difficulty busybox.exe was formerly, by default, built with globbing in the C runtime disabled. When BusyBox was run from the Windows command prompt it could behave in ways that didn't conform to expectations:

   C:\Users\rmy>busybox ls *
   ls: *: No such file or directory

   C:\Users\rmy>copy busybox.exe ls.exe
           1 files(s) copied.

   C:\Users\rmy>ls *
   ls: *: No such file or directory

However, this was necessary for the shell to work properly. Suppose we were in a directory containing a single file, a, which is a shell script:

   #!/bin/sh

   echo arg is "$1"
Here's what should happen when some commands are run in the directory. In each case the command includes a quoted question mark which the shell interprets literally as a question mark:
   $ env echo '?'
   ?
   $ (du '?')
   du: ?: No such file or directory
   $ ls a | grep '?'
   $ sh '?' b
   sh: can't open '?': Invalid argument
   $ ./a '?'
   arg is ?
   $ find . -name a -exec ls '?' \;
   ls: ?: No such file or directory
If busybox.exe behaved like a normal Windows command line program it would expand the '?'. The commands then worked like this:
   $ env echo '?'
   a
   $ (du '?')
   4       a
   $ ls a | grep '?'
   a
   $ sh '?' b
   arg is b
   $ ./a '?'
   arg is a
   $ find . -name a -exec ls '?' \;
   a
This is not how a Unix shell should behave.

This issue has been resolved by having the binary use Windows globbing if the environment variable BB_GLOBBING either doesn't exist or is set to a value other than 0. It then sets BB_GLOBBING=0 so that future invocations of the binary from the shell don't use Windows globbing.


Ron Yorston
13th April 2015 (updated 13th July 2020)