2

I always declare the shebang line #!/bin/bash in my shell script. Recently, when I called a script that contains an exit call, it killed my terminal. It usually kills the forked process and returned to my terminal prompt. Why might have happened that stopped the forking?

EDIT

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
  • I usually invoke script using . script_path or via a symlink to the script.
  • 1
    How did you invoke it? What version of bash is it? – Keith Mar 14 '11 at 2:29
5

The shebang never causes a process to fork.  It doesn't do anything UNLESS the script is executable and it is invoked in such a away that it causes the system to evaluate the shebang to see what program/shell to execute the script with.

If, for instance, you were already running in bash, and you executed the script with the source command, then the script would be executed inside the shell you were currently running, and the exit would affect that shell process, rather than it being a new shell process which got ended.

If you have a script file that you want to run, you should make it executable with the following command:

chmod +x script

Then, if you want to run the script, and if we assume that the script file is in the current directory, you use the following command:

./script

Note that this is very different from . script, which is just shorthand notation for source script.

The ./script is a relative pathname to the script file, which means search in the current directory to find the script file 'script' and then execute it — which works only if the script file is executable.

If you have script file that is NOT executable, then you can invoke it with:

bash script

But in this case you are specifying which shell to run and the shebang line is ignored.

  • Thank you for your reply. I run it by ". script". The strange thing happens intermittently. As I said, this didn't happen before. – Martin Mar 14 '11 at 3:04
  • 1
    The . is shorthand for the source command. If you want it to fork, you need to make the script executable, and then put it in your path somewhere, then you can execute it by typing the name, or if it is not in the path, by typing a pathname to the script. – Zeke Hansell Mar 14 '11 at 3:16
5

Since sourcing a script using . causes it to run in the current shell, an exit causes the current shell to exit. You can use return to return from a sourced script as well as from a function. You cannot return from a script that was run directly.

In order to work within these constraints, you can put a conditional test in your script to do the right thing depending on whether it's sourced or run directly.

As the first line after the shebang:

called=$_

At the point you want to exit or return:

[[ $called != $0 ]] && exit || return
  • Clever trick. Very useful for scripts that must be sourced to work properly, like python virtualenv activate scripts. – hobs Jul 12 '12 at 16:24
  • @hobs: I include the following line as the first line instead of a shebang in any scripts that must be sourced: [[ $_ != $0 ]] || { echo "This file must be sourced to have any effect."; exit 1; } – Dennis Williamson Jul 12 '12 at 18:22
  • I believe that this is backwards — it should be [[ "$called" = "$0" ]] && exit || return. (P.S. You should always quote all shell variable references unless you have a good reason not to, and you’re sure you know what you’re doing.) Another approach that is (arguably) more intuitive (requiring less head-scratching) is return 2> /dev/null || exit. – G-Man Jun 26 '17 at 20:02
  • @G-Man I believe you're wrong. As far.as quoting goes, it's unnecessary inside [[ ]] since word splitting etc don't occur there. – Dennis Williamson Jun 26 '17 at 22:21
4

The shebang does not cause a program to fork; whether or not the process forks is dependent on how the script is executed. Sourcing the script will cause it to run in the current interpreter, and using exec will replace the current process entirely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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