Bash – Why doesn’t source lib/* work

bashsource

I have a small program which contains the following folder structure:

- main.sh
- lib/
  - clean.sh
  - get.sh
  - index.sh
  - test.sh

Each file contains a single function which I use in main.sh.

main.sh:

source lib/*

get_products
clean_products
make_index
test_index

In the above the first two functions work but the second two don't.

Yet if I replace source lib/* with:

source lib/get.sh
source lib/clean.sh
source lib/index.sh
source lib/test.sh

Everything works as expected.

Anyone know why source lib/* doesn't work as expected?

Best Answer

Bash's source builtin only takes a single filename:

source filename [arguments]

Anything beyond the first parameter becomes a positional parameter to filename.

A simple illustration:

$ cat myfile
echo "param1: $1"
$ source myfile foo
param1: foo

Full output of help source

source: source filename [arguments]

Execute commands from a file in the current shell.

Read and execute commands from FILENAME in the current shell.  The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.

Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.

(This also applies to the equivalent "dot source" builtin . which, it's worth noting, is the POSIX way and thus more portable.)

As for the seemingly contradictory behavior you are seeing you can try running main.sh after doing set -x. Seeing what statements are getting executed and when may provide a clue.

Related Question