Mike Bannister
Mike Bannister

Reputation: 1524

source all files in a directory from .bash_profile

I need to allow several applications to append to a system variable ($PYTHONPATH in this case). I'm thinking of designating a directory where each app can add a module (e.g. .bash_profile_modulename). Tried something like this in ~/.bash_profile:

find /home/mike/ -name ".bash_profile_*" | while read FILE; do
source "$FILE"
done;

but it doesn't appear to work.

Upvotes: 75

Views: 56264

Answers (8)

str="$(find . -type f -name '*.sh' -print)"
arr=( $str )
for f in "${arr[@]}"; do
   [[ -f $f ]] && . $f --source-only || echo "$f not found"
done 

I tested this script and I am using it. Just modifiy the . after find to point to your folder with your scripts and it will work.

Upvotes: 1

sorin
sorin

Reputation: 170460

for file in "$(find . -maxdepth 1 -name '*.sh' -print -quit)"; do source $file; done

This solution is the most postable I ever found, so far:

  • It does not give any error if there are no files matching
  • works with multiple shells including bash, zsh
  • cross platform (Linux, MacOS, ...)

Upvotes: 5

Eugene Yarmash
Eugene Yarmash

Reputation: 149796

You can use this function to source all files (if any) in a directory:

source_files_in() {
    local dir="$1"

    if [[ -d "$dir" && -r "$dir" && -x "$dir" ]]; then
        for file in "$dir"/*; do
           [[ -f "$file" && -r "$file" ]] && . "$file"
        done
    fi
}

The extra file checks handle the corner case where the pattern does not match due to the directory being empty (which makes the loop variable expand to the pattern string itself).

Upvotes: 2

gaRex
gaRex

Reputation: 4215

Oneliner (only for bash/zsh):

source <(cat *)

Upvotes: 27

Yisrael Dov
Yisrael Dov

Reputation: 2449

I think you should just be able to do

source ~/.bash_profile_*

Upvotes: -7

mikejonesey
mikejonesey

Reputation: 200

ok so what i ended up doing;

eval "$(find perf-tests/ -type f -iname "*.test" | while read af; do echo "source $af"; done)"

this will execute a source in the current shell and maintian all variables...

Upvotes: -2

Cascabel
Cascabel

Reputation: 496902

I agree with Dennis above; your solution should work (although the semicolon after "done" shouldn't be necessary). However, you can also use a for loop

for f in /path/to/dir*; do
   . $f
done

The command substitution of ls is not necessary, as in Dirk's answer. This is the mechanism used, for example, in /etc/bash_completion to source other bash completion scripts in /etc/bash_completion.d

Upvotes: 22

Dirk is no longer here
Dirk is no longer here

Reputation: 368241

Wouldn't

 for f in ~/.bash_profile_*; do source $f; done

be sufficient?

Edit: Extra layer of ls ~/.bash_* simplified to direct bash globbing.

Upvotes: 114

Related Questions