Loading shell functions
First of all some thoughts about when and where to load
shell functions.
Configuration files: In principle shell functions can
be defined in one of the configuration files
(.profile , .bashrc etc.), so that the shell
loads them automatically. However,
it doesn't make sense to load all existing functions on every
shell start. Some (such as bash completion) only apply to
interactive shells, others are only required by specific
scripts. In non-interactive shells one shouldn't pre-define any
functions at all, but provide each script with a clean environment
and load required functions in the script, using
. file or source file .
In doing so, it is also recommended to avoid absolute paths,
which cause strong coupling with the system environment and reduce
portability. A better way is to use the shell's search facility.
Search: If the parameter supplied with
. file or source file
represents a simple name, the shell searches the directories contained
in $PATH for a file of the given name. The first one
found will be sourced. The shell expects it to define the
respective function; if that isn't the case, it tries to
call it as a script. To make use of the search facility,
each function has to be put in a separate file named after
the function. The file may contain other things as well, like
auxiliary functions, but such side effects should be restricted
to a minimum. The function definitions are concentrated in a few directories,
and the absolute paths of the directories are added to the
setting of $PATH ,
as usual separated by : . All this can be done in
a profile file. Afterwards functions can be loaded by
simply supplying their name, i.e. by source functionname .
Autoload: The Kornshell provides an additional autoload mechanism. To use it,
one does like described above and additionally sets the exported
variable FPATH to a list of the function directories. In other words,
$FPATH must be a subset of $PATH . If these conditions
are met, ksh does a search for any function being called but
not yet defined, and loads it automatically if found. No explicit source
is required.
While this is quite convenient, it can also have its
drawbacks. If a function func is called exclusively in the form
$(func parameter...) (i.e., in subshells),
it will be looked up and loaded on every call, which is
inefficient.
[1] In this case it's better to source the function explicitly once
at the start of the script. The definition will then automatically
be passed to subshells. Note, however, that this must happen exactly
once. If func is already defined, source func will be
a call instead of a redefinition.
To make sure, either provide the absolute path of the function file
instead of the name, or prepend a condition:
typeset +f func >/dev/null || source func
[1] In ksh93t there will be a more efficient
command substitution ${command} , which will
run the command in the current shell (thanks to David Korn).
|