I have the following setup
└── modules
├── main.sh
├── major.sh
├── sub-modules
│ └── minor.sh
/modules
to $PATH.all.sh:
source major.sh
major.sh:
source sub-module/minor.sh
But when I run this I get:
-bash: /sub-module/minor.sh: No such file or directory
Yes. This is how the .
/source
operator works.
From the spec:
The shell shall execute commands from the file in the current environment.
If file does not contain a <slash>, the shell shall use the search path specified by PATH to find the directory containing file. Unlike normal command search, however, the file searched for by the dot utility need not be executable. If no readable file is found, a non-interactive shell shall abort; an interactive shell shall write a diagnostic message to standard error, but this condition shall not be considered a syntax error.
So when you use source file.sh
the shell searches in the $PATH
but when you use source dir/file.sh
the $PATH
lookup is skipped and dir
is assumed to be relative to the current directory.
To do this sort of thing (internally to main.sh
or major.sh
) you could use Can a Bash script tell what directory it's stored in? to find the appropriate absolute path to use.
For general use you are going to need to stick them all in $PATH
or source
them from absolute/etc. paths.
Path lookups only occur on names that don't contain a /
. Also, only the immediate contents of a directory in PATH
is checked, not all its subdirectories. With source sub-module/minor.sh
, sub-module
must be in the current directory. You would have to add /path/to/modules/sub-module
to your path as well, then source minor.sh
alone.
You can keep that to one line if you want:
PATH=/path/to/modules/sub-module:$PATH source minor.sh
This only updates PATH
for this single source
command.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With