$PATH
in bash
The $PATH
environment variable does not support glob patterns. If you add something with a glob pattern (e.g. *
), bash
ignores it. Observe:
# create a couple of executables for testing.
$ mkdir -p /test/foo/bin /test/bar/bin
$ echo "echo 'executable foo'" > test/foo/bin/foo
$ echo "echo 'executable bar'" > /test/bar/bin/bar
$ chmod +x /test/foo/bin/foo /test/bar/bin/bar
# we don't expect the shell to find `foo`,
# because it is not in the `$PATH`.
$ foo
bash: foo: command not found
$ export PATH="/test/*/bin:$PATH"
$ echo $PATH
/test/*/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# we still don't expect the shell to find `foo`,
# because `$PATH` does not support glob patterns.
$ foo
bash: foo: command not found
As you can see, if we add glob patterns directly to our $PATH
it simply does not work. However, we can use bash
to “evaluate” our glob pattern and proceed to update $PATH
with the resulting array of oridinary directories. Fortunately, the (...)
construct makes this very easy for us:
$ extra_directories=(/test/*/bin)
$ echo ${extra_directories[@]}
/test/bar/bin /test/foo/bin
$extra_directories
is an array with two elements, corresponding to the two bin
directories we’ve created above. Next, we have to join the array into a string, using :
as the separator. No problem with printf
:
$ extra_path=$(printf "%s:" "${extra_directories[@]}")
$ echo $extra_path
/test/bar/bin:/test/foo/bin:
$extra_path
now contains a valid $PATH
string. The last thing we have to do, is to update and export
the $PATH
variable itself:
$ export PATH="${extra_path}${PATH}"
$ echo $PATH
/test/bar/bin:/test/foo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# both, `foo` and `bar` are now in our `$PATH`:
$ foo
executable foo
$ bar
executable bar
Here is the complete script:
$ extra_directories=(your/*/glob/*/pattern)
$ extra_path=$(printf "%s:" "${extra_directories[@]}")
$ export PATH="${extra_path}${PATH}"
Notes
Software: Ubuntu 14.04 LTS with bash
(version 4.3.30).