What is the purpose of "source" (.) as a shell command?
Command (A) is called sourcing the file which consists of shell commands. It may not be used for binary executables (see man file
for information on how to determine a file's type). It causes the commands in the file to be executed in the current environment as if they were typed at the shell prompt. The results affect the current environment and so can do things like set the value of environment variables and change directories, adding function definitions, among other things. It is not necessary to set the execution bit using chmod. The file needs to be in the current directory or a full or relative path* must be included or the file can be in a location that's in the PATH
environment variable (subject to whether the sourcepath
option of shopt
is set). It is not necessary to specify the current directory if that is where the file is located. These are all equivalent:
$ ls
filename
$ . filename
results
$ ls /some/directory/filename
/some/directory/filename
$ . /some/directory/filename
results
$ cd /elsewhere
$ echo $PATH
/some/directory
$ . filename
results
Command (B) causes the shell to execute the file only if the execution bit is on for the rights of the user (see man chmod
). The file may be a shell script, a binary executable or another script such as Perl or Python (or written in a different shell). If there is no slash in the name (no directory is specified) then the file must be located in a directory that is included in the PATH
environment variable. It is possible to include the current directory in the path, but I don't recommend it because it's a security risk. These are equivalent:
$ echo $PATH
/some/directory
$ filename
results
$ /some/directory/filename
results
Command (C) is essentially the same as command (B), but it specifies the current directory which is referred to as "." (just as the parent directory is referred to as "..". The PATH will not be searched to locate the file since a directory is specified.
[*] A relative path is one that does not start with a slash (/). It specifies a location relative to the current directory. "this/is/a/subdir" exists as a directory path under the current one as does "./this/is/a/subdir" (which specifies the same directory). "../another/set/of/dirs" is a set of directories below the parent of the current one.
If you source a script with
# . script
or
# source script
means that the script runs in the current shell.
If you run
# ./script
It will run in a new shell and will not have access to variables set in the current shell that have not been exported into the environment with "export".
Using the ". <executable>"
runs the executable in the context of the running shell. If you set variables in the script, they will persist in shell that you source them from.
Normal behavior when you execute a program or script is to instantiate a new shell and launch the process. (That's why scripts start with #!/bin/sh
, #!/bin/perl -w
, etc -- that prescribes the shell and options to use)
"Sourcing" the script is useful for loading environment variables specific to an application, typically a database or development environment. If you run multiple Oracle or other database instances, you may have a set of "source" or "environment" scripts for the production, dev, and QA environments. If you have a compile farm that targets multiple platforms (ie. producing Solaris binaries from a Linux farm), you may have these scripts to easy load the proper environment variables.