Over the years I have collected a few shell snippets that have to be sourced or called as shell functions to work correctly. Having all these function definitions in a monolithic file sourced from my .bashrc isn’t cool, so for some time I’ve had the following in my .bashrc:
for i in $HOME/.lib.sh/* ; do
source $i
done
This has at least one obvious downside. Each time I change a function definition I have to reload the function i each and every open shell if I want a consistent work environment. Today I came up with a nifty solution. Each file in ~/.lib.sh which previously contained a function definition isedited to only contain the function body. The I add the following new function called load_functions:
FUNCTIONS=$HOME/.lib.sh
eval $(
find $FUNCTIONS -type f | \
while read file ; do echo function $(basename $file)\(\) { source $file\; }\; ; done
)
For each file under ~/.lib.sh a new function is automatically defined which just sources the real file. This means I can edit the files without having to reload the function in every open shell. ~/.lib.sh/load_files itself is just sourced from my .bashrc.
One of my functions wraps the wonderful Perl5 module local::lib. This module makes it easy to manage multiple sandboxes with locally installed Perl modules. It works by setting a couple of environment variables including $PERL5LIB. Instead of using local::lib directly I used a function called perllibs:
# Defaults:
PERL_LOCAL_LIB="home"
DIR=$HOME/.perl
if [ -n "$1" ]; then
PERL_LOCAL_LIB=$1
fi
export PERL_LOCAL_LIB
case $PERL_LOCAL_LIB in
alpha)
DIR=$HOME/projects/alpha/ ;;
mercury)
DIR=$HOME/subversion/mercury/perl ;;
tmp)
mkdir -p /tmp/makholm/perl
DIR=/tmp/makholm/perl ;;
esac
eval $( perl -Mlocal::lib=$DIR )
Adding new projects to this list would be a hassle if I had to reload the file in multiple shells each time.