. is the Bourne and POSIX shell command while
source is the C-Shell command.
Some Bourne-shell derivatives like
zsh and most implementations of
ksh also have a
source command which is generally an alias for
. - however, it may behave slightly differently (e.g. in zsh and ksh).
source behave the same, but their behaviour is affected by whether they are run in POSIX mode or not¹.
POSIX requires that the
. command exits the shell process² if it can't open the file for reading and requires that the file be found through a search of the directories in
$PATH if the provided path doesn't contain a
source interprets the argument as a path, and never looks the file up in
source behave as POSIX requires when in POSIX mode, and as pdksh's
source when not, that is they don't exit the script if they fail to open the file for reading (same as
command .) and lookup the file in
$PATH and the current directory if the provided path doesn't contain a
. behaves as POSIX requires, while
source looks in the current directory first and then
$PATH (even in
csh emulation) when the argument doesn't contain a
info zsh . and
info zsh source for details). If
source fail to find/open the file, that only aborts the shell when in POSIX mode (
sh emulation) though.
source doesn't exit the shell either but doesn't look for the file in the current directory.
All in all, in Bourne-like shells (though not the Bourne shell that doesn't have a
command builtin), if you want a consistent behaviour, you could do
command . /path/to/the-file-to-source || handle-error
And if the-file-to-source is meant to be in the current directory, be sure to write:
command . ./the-file-to-source || handle-error
sh scripts (where
sh is a POSIX
sh) you should be able to rely on the POSIX behaviour stated above.
bash enable the POSIX mode when called as
bash, also when it receives
POSIXLY_CORRECT in its environment (even when called as bash even though there's no POSIX command called
bash), or when it receives
SHELLOPTS=posix, or when called with
bash --posix or
bash -o posix or after a
set -o posix. With zsh, you use
emulate sh to emulate
sh. Emulations alter a whole bunch of options that change the behaviour of zsh. In this case, the option is
In bash, you can check if in POSIX mode or not with the (non-POSIX),
[ -o posix ] command. In zsh, you check the output of
emulate to see if you're in
sh emulation, or
[[ -o posixbuiltins ]] to check whether that particular option is enabled. You can also temporarily enable a given emulation mode with
emulate -L (to emulate in the current local scope only).
² for non-interactive shells. For interactive shells, the behaviour varies between shells, some ignore the failure, some will return to the prompt like some syntax errors would. Also, when run in a subshell, that exits the subshell only.