[bash] How best to include other scripts?

Shell Script Loader is my solution for this.

It provides a function named include() that can be called many times in many scripts to refer a single script but will only load the script once. The function can accept complete paths or partial paths (script is searched in a search path). A similar function named load() is also provided that will load the scripts unconditionally.

It works for bash, ksh, pd ksh and zsh with optimized scripts for each one of them; and other shells that are generically compatible with the original sh like ash, dash, heirloom sh, etc., through a universal script that automatically optimizes its functions depending on the features the shell can provide.

[Fowarded example]

start.sh

This is an optional starter script. Placing the startup methods here is just a convenience and can be placed in the main script instead. This script is also not needed if the scripts are to be compiled.

#!/bin/sh

# load loader.sh
. loader.sh

# include directories to search path
loader_addpath /usr/lib/sh deps source

# load main script
load main.sh

main.sh

include a.sh
include b.sh

echo '---- main.sh ----'

# remove loader from shellspace since
# we no longer need it
loader_finish

# main procedures go from here

# ...

a.sh

include main.sh
include a.sh
include b.sh

echo '---- a.sh ----'

b.sh

include main.sh
include a.sh
include b.sh

echo '---- b.sh ----'

output:

---- b.sh ----
---- a.sh ----
---- main.sh ----

What's best is scripts based on it may also be compiled to form a single script with the available compiler.

Here's a project that uses it: http://sourceforge.net/p/playshell/code/ci/master/tree/. It can run portably with or without compiling the scripts. Compiling to produce a single script can also happen, and is helpful during installation.

I also created a simpler prototype for any conservative party that may want to have a brief idea of how an implementation script works: https://sourceforge.net/p/loader/code/ci/base/tree/loader-include-prototype.bash. It's small and anyone can just include the code in their main script if they want to if their code is intended to run with Bash 4.0 or newer, and it also doesn't use eval.