Reputation: 147
I have folder with number of different files that contains functions. I use declare to publish those functions to users. This is sample function I use:
space () {
df -h
}
declare -f space
Under user .bashrc I have added following:
for FILE in $HOME/functions/* ; do source $FILE ; done
However I get this message:
-bash: source: /home/user/functions/subdirectory: is a directory
Can anyone advise how to fix that or maybe there is better way to load functions to shell variables not to environment variables?
Upvotes: 0
Views: 759
Reputation: 147
Thanks for all answers and here is the update what works for me.
MYFUNC=$(find ~/functions -type f)
for f in $MYFUNC ; do
source $f > /dev/null 2>&1
done
Thanks for help
Upvotes: 1
Reputation: 140880
Just check if the file exists. Also, quote variable expansions. Prefer lower case variables.
for file in "$HOME"/functions/* ; do
if [[ -f "$file" && -r "$file" ]]; then
source "$file"
fi
done
This is portable to posix shell (just change [[
to [
and ]]
to ]
) and is just usually written that way. I'm sure you'll find such loop in your /etc/profile
. I've found some similar in bash-completion script.
Upvotes: 4
Reputation: 9445
I would correct xdhmoore's answer like this:
while read -d $'\0' file; do
source "$file"
done < <(find $HOME/functions -type f -print0)
Indeed, using a pipe will prevent the current environment to be modified, which is one of the primary goal of the source
command.
Example of the pipe problem: let's create the file ~/functions/fff
like this (and let's assume it's the only file into ~/functions
):
a=777
Then run find ~/functions -type f | while read f; do source "$f"; done; echo $a
: you will have no output.
Then run while read f; do source "$f"; done < <(find ~/functions -type f); echo $a
: you will have this output: 777
.
The reason of that behaviour is that a command piped with |
is running in a subshell, then the subshell environment will be modified, not the current one.
Upvotes: 2