RAF
RAF

Reputation: 147

how to find file and run as source script?

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

Answers (3)

RAF
RAF

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

KamilCuk
KamilCuk

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

yolenoyer
yolenoyer

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

Related Questions