.
is the Bourne and POSIX shell command while source
is the C-Shell command.
Some Bourne-shell derivatives like bash
, 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).
For bash, .
and 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 /
.
csh
's source
interprets the argument as a path, and never looks the file up in $PATH
.
bash .
and 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 /
.
zsh .
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 /
. (see info zsh .
and info zsh source
for details). If .
or source
fail to find/open the file, that only aborts the shell when in POSIX mode (sh
emulation) though.
AT&T ksh's 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
In sh
scripts (where sh
is a POSIX sh
) you should be able to rely on the POSIX behaviour stated above.
¹ zsh
and bash
enable the POSIX mode when called as sh
. For 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 POSIX_BUILTINS
.
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.
zsh
uses the current working directory if the path doesn't contain any/
withsource
but not with.
. Or maybe that has changed in the meanwhile? – Walter Tross Feb 17 '20 at 14:05