Monday, December 15, 2014

Shell Scripting : Which gets executed - shell specified in shebang(#!) or shell specified in command line

Suppose I have an executable script, test.sh as follows

#!/bin/bash

readlink /proc/$$/exe

When I run the above script as ./test.sh, then I know that bash shell executes the script. Then the output of above script is

$ ./test.sh
/bin/bash

If I run the above script as follows

$ /bin/csh test.sh

Which shell will execute the script - csh(specified in the command line) or bash(specified in the shebang)?

The output of the the above command is /bin/csh.

So why does /bin/csh execute the script instead of /bin/bash specified in the script?

Here is the answer,

Whenever a shell script is executed, a new shell(process) is spawned(forked) and the commands in the scripts are executed. The child shell becomes the parent process of commands in the script.
The shebang, #!, is used by the exec() family of functions to determine whether the file to be executed is a binary or script. If the shebang(#!) is present, then exec() will run the executable specified after the shebang - in the above case it is /bin/bash. she-bang is actually a two byte magic number that designates a file type. Immediately following the she-bang(#!) is the path name - this is the path to the program that interprets the commands in the script whether it be a shell, programming language or a utility. This command interpreter then executes the commands in the script starting at the top(following the shebang #! line), ignoring commands.

Now if you run the script by specifying the shell in the command line, like /bin/csh test.sh, the exec() will execute the shell interpreter, /bin/csh specified in the command line instead of looking into the script for shell interpreter specified in shebang line.


No comments:

Post a Comment