Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have one bash source as follows,

if [ $# -ne 1 ]; then

when I execute it in two ways, there are different behaviors. The first way is,


It will close the terminal after execution. The second way is,


this will simply finish running the script, and stay on the terminal. I am asking if there is a command for exiting a bash scripts for both source and ./ execution. I have tried return too, which does not work well under ./ execution.

More generally, I am interested in why this is happening, and what's difference between using "source" and "." for script execution?

share|improve this question
up vote 8 down vote accepted

Before answering, I think some clarifications are needed. Let's analyze the following three lines:


The first two lines are exactly identical: . is in fact an alias for source. What source does is executing the shell script in the current context, hence a call to exit will quit the shell.

The third line (which is the one that confuses you) has however nothing to do with the other lines. ./ is just a path, and is the same as (for example) /home/user/ or /usr/bin/something. Always remember that commands in the shell are separated by a space. So, in this case, the command is not ., but is ./ this means that a sub-shell will be executed and that the exit will have effect just to the sub-shell.

share|improve this answer

Three ways:

You can enclose the script in a function and only use return.

#!/usr/bin/env bash
main() {
    return 1
main "$@"

You can test if the script is being sourced by an interactive shell.

if [[ $- = *i* ]]; then
    return 1
    exit 1

You can try to return, and if it fails, exit.

return 1 2>/dev/null || exit 1
share|improve this answer
Any hints as to how the magic incantation $- = *i* works? – deadbeef404 May 9 at 6:47
@deadbeef404 The special parameter - holds the currently active option flags. The test checks if the -i flag is active. See – geirha May 9 at 12:22

Think of the command 'source' as in 'include' statement. It takes the content of the argument and runs it as though it were ran directly. In this case your command is 'source' with an argument of '' and is executed exactly as though you had typed the content of into your command line.

When you run './', './' is your command and it has no arguments. Since this file is plain-text and not binary, your shell looks for an interpreter at the shebang ('#!' on the first line) and finds '/bin/bash'. So your shell then starts a new instance of bash and the content of is run inside this new instance.

In the first instance, when bash reaches the 'exit' command it is executed exactly as though you had typed it into the command line. In the second instances it is executed in bash process your shell started, thus only this instance of bash receives an 'exit' command.

When you type a line into bash, anything before the first space is treated as a command and anything that follows are treated as arguments. The command '.' is an alias of 'source'. When you run '.' the '.' is a command on it's own as it is separated from it's arguments by a space. When you run './' your command is './' and '.' is part of the relative path to with the '.' representing your current folder.

share|improve this answer
If you are a C/C++ programmer looking to get better with shell/bash scripting this is the perfect answer. – jucestain Jan 18 at 17:10

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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