Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This question already has an answer here:

I am confused by "one only dot - space - shell script name" (like . myshellscript) and "path to shell script" (like ./myshellscript) commands.

What for they are? I noticed the command . myshellscript executes shell script even with -rw-rw-r--. But ./myshellscript doesn't. So I am confused.

share|improve this question

marked as duplicate by Gilles, Renan, jasonwryan, warl0ck, rahmu Feb 22 '13 at 7:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
When in doubt, use ./foo. That executes the script, which you usually want. –  dancek Feb 21 '13 at 14:21

5 Answers 5

up vote 8 down vote accepted

Others have said the difference is sourcing vs executing but no one has outlined the functional differences.

The biggest functional difference is that exit, cd, and variable assignments will affect the currently running shell if you source it, but not if you execute it. To demonstrate, try the following:

$ cat test.sh
#!/bin/bash

mkdir -p test
cd test
pwd

foo=bar
echo script foo: $foo

$ ./test.sh
/Users/kevin/test
script foo: bar
$ echo $foo

$ pwd
/Users/kevin
$ . test.sh
/Users/kevin/test
script foo: bar
$ echo $foo
bar
$ pwd
/Users/kevin/test
$ 

Now try this:

$ cat test.sh
#!/bin/bash
exit
$ ./test.sh
$ . test.sh

[Process completed]

As you can see, exit in an executed script will finish that script, but if you source a script with exit, it will exit your current shell!

share|improve this answer
    
+1 for demonstrating a function difference. –  LarsH Feb 21 '13 at 21:59

help source says:

source: 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.

source is a synonym for ., that means you can write both

. myshellscript

or

source myshellscript

What they do: source reads every line of the file (line by line) and executes it in the current shell.

But ./myshellscript executes the file in the current directory if it has the rights to do so. This could also be

/tmp/foo/bar/myshellscript

(to execute the file myshellscript which is in the directory /tmp/foo/bar) or

/usr/local/bin/myshellscript

That means, that here the dot is just the current directory. Therefore ./myshellscript executes the file called myshellscript in the current directory.

For example try

cd .

which changes to the current directory (no real change ;-)) or

ls .

which lists the content of the current directory.


And as @Alvin Wong commented: You can try this script

#!/bin/foobarNonExisting

echo "This is the Shell that executes me:"
echo $SHELL

with . or source to see, that it does not read the shebang. It just uses your current shell. Executing the script itself would lead to an error.

share|improve this answer
    
@YarLinux you haven't set the executable bit on myshellscript. Run chmod u+x myshellscript and try again. –  Kevin Feb 21 '13 at 14:41
    
Because source myshellscript does not execute the script. But reads every line of the file (line by line) and executes it. That is a difference. And this only works if your file is a shell script. A python script wont work. Neither a binary file. For them you only have the ./mypythonfile option. Or python mypythonfile. –  erik Feb 21 '13 at 14:43
1  
Oh? So it means that using . or source doesn't read the shebang, and sh script will be executed by bash? –  Alvin Wong Feb 22 '13 at 2:44
    
@Alvin Wong Exactly. –  erik Feb 24 '13 at 6:20

In bash, . and source functionally perform the same job -- running a script inside the current shell.

./foo runs inside another shell, as your shell forks before execution.

If your script should be portable, always use .. source is a bash synonym, but it does not exist in (for example), the POSIX shell.

share|improve this answer

. is a synonym to the source command. Instead of forking a sub shell to execute the script it reads the script into the current shell environment. In other words ./script will execute the script in a spawned sub shell and does the processing there. Where . script reads the script into your current shell where your current shell will process the commands.

They do the similar things. With . script you are reading and ./script you are executing (by spawning a sub shell) so the appropriate permissions are required to do either.

share|improve this answer
5  
Effectively they do a different thing, try running a script containing exit. –  choroba Feb 21 '13 at 14:18
    
You're right. I changed it. I hadn't thought of that originally. –  h3rrmiller Feb 21 '13 at 14:20

There are many answers explaining that . ~/bin/script.sh is equivalent to source ~/bin/script.sh. Here's the explanation of why.

I have several clusters that I use for testing, and I use environment variables to point to them. Normally when you run a script, any variables set in it stay in the scope of that script. In example:

$ echo $MYFIELD #Nothing set

$ cat test.sh
export MYFIELD=foo #This would set it
$ ./test.sh
$ echo $MYFIELD #Didn't work because the script didn't carry it back to its parent

$ . ./test.sh
$ echo $MYFIELD #When run as a sourced script, this stayed in the context of my current shell
foo

In this way, I can type . ~/env/cluster7 and then run any commands I want on that cluster, then type . ~/env/cluster3 to change all my environment variables to point to another one without having to manually set them.

Notice that "." at the start of a line followed by a space is interpreted as a command. This is OK because you'd never execute the only file that can be named that way: the current directory. In any other context, though, such as without a following space or at any point later in the command line, it refers to the path, hence . ./test.sh. Since it is considered a command by bash, . test.sh also works.

share|improve this answer
    
So, to paraphrase this as a when... you would use . (or source) when you want to run a set of shell commands from a file in order to set environment variables or change the current directory in your current shell process (the shell from which you're running the source command). –  LarsH Feb 21 '13 at 22:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.