Kim Spasaro

Bash Globbing and Filename Expansion

April 23, 2017 ,

What is globbing?

Bash allows you to express multiple paths in a single string by using the * wildcard. Globbing or filename expansion is the process where bash expands the * wildcard to match files and directories in a path. For example, echo “$HOME/*” returns the paths for all files in a user’s home directory (excluding hidden files!).

$ echo "$HOME/*"
/home/kim/desktop /home/kim/dev /home/kim/documents /home/kim/downloads

In the above example you can see how globbing expanded the * wildcard to match files in my home directory. You can use the * wildcard in a variety of different ways.

$ echo "$HOME/d*s"
/home/kim/documents /home/kim/downloads
$ echo "$HOME/de*"
/home/kim/desktop /home/kim/dev

Why use globbing?

You might be wondering what filename expansion is useful for. Here’s a practical example. Programs typically keep their executable files in a directory named bin. Adding the path to a program’s bin directory allows you to run its executable file(s) from the command line by typing the filename. For example, I have added to my PATH variable the path to a tool I developed called Subspace.

# /home/kim/.bashrc
export PATH="/home/kim/dev/tools/subspace/bin:$PATH"

When I type sub bash checks to see if /home/kim/dev/tools/subspace/bin/sub exists and is executable. If both these conditions are true, the file runs.

This is great, but what if I want to be able to execute multiple different tools in my /home/kim/dev/tools directory, each with its own bin directory? I can add each path to my PATH variable, like so:

# /home/kim/.bashrc
export PATH= \
  "/home/kim/dev/tools/subspace/bin": \
  "/home/kim/dev/tools/terraform/bin": \
  "/home/kim/dev/tools/aws/bin": \
  "$PATH"

Or…

(I bet you can guess where this is going…)

(the suspense is building…)

I can add a single line that takes advantage of file globbing!

# /home/kim/.bashrc
export PATH="$(echo $HOME/dev/tools/*/bin | sed -n 's/\s/:/pg'):$PATH"

Now I can run executables in the bin directory of any tool in my tools directory.

What’s going on here?

Note that the PATH export in my .bashrc file exports only the string I provide it and does not perform globbing on its own, so I’ve added a few commands to make the export do what I want. The echo command returns the globbed paths:

$ echo $HOME/dev/tools/*/bin
/home/kim/dev/tools/subspace/bin /home/kim/dev/tools/terraform/bin /home/kim/dev/tools/aws/bin

while the sed command replaces the spaces with colons and prints the resulting string:

$ echo $HOME/dev/tools/*/bin | sed -n 's/\s/:/pg
/home/kim/dev/tools/subspace/bin:/home/kim/dev/tools/terraform/bin:/home/kim/dev/tools/aws/bin