11

OK, so source runs the script in the current shell and . separately, as detailed in running script with ". " and with "source " for example, but, specifically, in my .bashrc file, I have:

[ -f ~/.bash_aliases ] && source ~/.bash_aliases
[ -f ~/.git-completion.bash ] && source ~/.git-completion.bash
[ -s ~/.autojump/etc/profile.d/autojump.sh ] && source ~/.autojump/etc/profile.d/autojump.sh

Can I replace this with:

[ -f ~/.bash_aliases ] && . ~/.bash_aliases
[ -f ~/.git-completion.bash ] && . ~/.git-completion.bash
[ -s ~/.autojump/etc/profile.d/autojump.sh ] && . ~/.autojump/etc/profile.d/autojump.sh

Will that work on OS X - is that the "POSIX" issue?

I tried it and the above still seem to work on Ubuntu (so they actually work with both source and ., that is, they give me the desired functionality in the shell). Should I choose one over the other, or am I missing something?

FWIW, on OS X, I source my .bashrc from my .bash_profile.

2
  • 1
    If it is 'sh' based shells I'd be using '.' for global compatibility and if you are using 'csh' based shells I'd be using source.
    – mdpc
    Commented May 10, 2014 at 20:40
  • 2
    Where in the linked post are you seeing that "source runs the script in the current shell and . separately"? They both run it in the current shell; otherwise there'd be no point Commented May 10, 2014 at 21:01

2 Answers 2

20

In bash, . and source are synonyms. Looking into bash source code, file builtin/source.def, you can see . and source use the same internal function source_builtin:

$BUILTIN source
$FUNCTION source_builtin
$SHORT_DOC source filename [arguments]
Execute commands from a file in the current shell.

Read and execute commands from FILENAME in the current shell.  The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.

Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.
$END

$BUILTIN .
$DOCNAME dot
$FUNCTION source_builtin
$SHORT_DOC . filename [arguments]
Execute commands from a file in the current shell.

But source is not POSIX compatible, so if your script is called with POSIX /bin/sh, you should use . instead of source. Since POSIX doesn't restrict the shell, all your above script will work.

Personally, I always use . instead of source. (A lot of scripts that I wrote run under cron).

2
  • All things being equal, use "source" instead of "." for one reason: try to search/grep for "." expressions in a large script. It's a nightmare.
    – abonet
    Commented May 16, 2014 at 20:44
  • Although this answer explains why using . is usually "better" than using source, as @abonet says, source is a lot easier to search for. Since periods are punctuation in many languages, it's easy for the eye to just skip over them. That's why I prefer to use source.
    – Joe
    Commented May 16, 2014 at 23:01
11

This is POSIX's definition of .dot:

The shell shall execute commands from the file in the current environment.

If file does not contain a /<slash>, the shell shall use the search path specified by $PATH to find the directory containing file. Unlike normal command search, however, the file searched for by the .dot utility need not be executable. If no readable file is found, a non-interactive shell shall abort; an interactive shell shall write a diagnostic message to standard error, but this condition shall not be considered a syntax error.

Considering the above, you might as well just replace your [ -f ./file ] && source ./file with . ./file altogether. If the file is not there the worst that will happen is you'll get a notice at login - which is probably information you'd want to have, I think.

Of course if you'd rather keep the test you could do:

test -f ./file && . $_
4
  • 2
    Oh, people knowing $_, I like that. :) Commented May 10, 2014 at 21:24
  • @AndreasWiese - everyone should - it's one of only some 7 special parameters defined by POSIX.
    – mikeserv
    Commented May 10, 2014 at 21:43
  • +1 I ended up using the test -f /.file && . $_ approach shown here Commented May 11, 2014 at 10:29
  • 6
    @mikeserv No, $_ is not standardized by POSIX. The 8 special parameters are $@, $*, $#, $$, $!, $?, $- and $0. $_ is explicitly omitted. Your incorrect comment sparked a question. Commented May 13, 2014 at 23:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .