22

At a unix command line, what's the difference between executing a program by simply typing it's name, vs. executing a program by typing a . (dot) followed by the program name? e.g.:

runme

vs.

. runme
dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
Landon Kuhn
  • 76,451
  • 45
  • 104
  • 130

5 Answers5

26

. name sources the file called name into the current shell. So if a file contains this

A=hello

Then if you sources that, afterwards you can refer to a variable called A which will contain hello. But if you execute the file (given proper execution rights and #!/interpreterline), then such things won't work, since the variable and other things that script sets will only affects its subshell it is run in.

Sourcing a binary file will not make any sense: Shell wouldn't know how to interpret the binary stuff (remember it inserts the things appearing in that file into the current shell - much like the good old #include <file> mechanism in C). Example:

head -c 10 /dev/urandom > foo.sh; . foo.sh # don't do this at home!
bash: �ǻD$�/�: file or directory not found

Executing a binary file, however, does make a lot of sense, of course. So normally you want to just name the file you want to execute, and in special cases, like the A=hello case above, you want to source a file.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
17

Using "source" or "." causes the commands to run in the current process. Running the script as an executable gives it its own process.

This matters most if you are trying to set environment variable in current shell (which you can't do in a separate process) or want to abort the script without aborting your shell (which you can only do in a separate process).

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
5

The first executes the command. The second is shorthand for including a shell script inside another.

Mr. Shiny and New 安宇
  • 13,822
  • 6
  • 44
  • 64
4

This syntax is used to "load" and parse a script. It's most useful when you have a script that has common functionality to a bunch of other scripts, and you can just "dot include" it. See http://tldp.org/LDP/abs/html/internal.html for details (scroll down to the "dot" command).

Mike
  • 4,542
  • 1
  • 26
  • 29
  • +1 for the link about the dot-command -> `This command, when invoked from the command-line, executes a script. Within a script, a source file-name loads the file file-name. Sourcing a file (dot-command) imports code into the script, appending to the script (same effect as the #include directive in a C program). The net result is the same as if the "sourced" lines of code were physically present in the body of the script. This is useful in situations when multiple scripts use a common data file or function library.` – Levite Jul 17 '14 at 08:15
  • Boo, hiss for linking to the ABS (it's notorious in the bash community for bad-practice examples and outdated content). A more canonical reference source would be [the POSIX specification for `dot`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#dot). – Charles Duffy Nov 22 '21 at 12:53
4

Running "runme" will create a new process which will go on its merry little way and not affect your shell.

Running ". runme" will allow the script "runme" to change your environment variables, change directories, and all sorts of other things that you might want it to do for you. It can only do this because it's being interpreted by the shell process that's already running for you. As a consequence, if you're running bash as your login shell, you can only use the "." notation with a bash script, not (for example) a binary on C shell script.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415