Shell Scripting – Which Interpreter Runs a Script with No Shebang?

bashshebangshellshell-scriptzsh

Suppose the default shell for my account is zsh but I opened the terminal and fired up bash and executed a script named prac002.sh, which shell interpreter would be used to execute the script, zsh or bash? Consider the following example:

papagolf@Sierra ~/My Files/My Programs/Learning/Shell % sudo cat /etc/passwd | grep papagolf
[sudo] password for papagolf: 
papagolf:x:1000:1001:Rex,,,:/home/papagolf:/usr/bin/zsh
# papagolf's default shell is zsh

papagolf@Sierra ~/My Files/My Programs/Learning/Shell % bash
# I fired up bash. (See that '%' prompt in zsh changes to '$' prompt, indicating bash.)

papagolf@Sierra:~/My Files/My Programs/Learning/Shell$ ./prac002.sh 
Enter username : Rex
Rex
# Which interpreter did it just use?

**EDIT : ** Here's the content of the script

papagolf@Sierra ~/My Files/My Programs/Learning/Shell % cat ./prac002.sh 
read -p "Enter username : " uname
echo $uname

Best Answer

Because the script does not begin with a #! shebang line indicating which interpreter to use, POSIX says that:

If the execl() function fails due to an error equivalent to the [ENOEXEC] error defined in the System Interfaces volume of POSIX.1-2008, the shell shall execute a command equivalent to having a shell invoked with the pathname resulting from the search as its first operand, with any remaining arguments passed to the new shell, except that the value of "$0" in the new shell may be set to the command name. If the executable file is not a text file, the shell may bypass this command execution. In this case, it shall write an error message, and shall return an exit status of 126.

That phrasing is a little ambiguous, and different shells have different interpretations.

In this case, Bash will run the script using itself. On the other hand, if you ran it from zsh instead, zsh would use sh (whatever that is on your system) instead.

You can verify that behaviour for this case by adding these lines to the script:

echo $BASH_VERSION
echo $ZSH_VERSION

You'll note that, from Bash, the first line outputs your version, while the second never says anything, no matter which shell you use.

  • If your /bin/sh is, say, dash, then neither line will output anything when the script is executed from zsh or dash.
  • If your /bin/sh is a link to Bash, you'll see the first line output in all cases.
  • If /bin/sh is a different version of Bash than you were using directly, you'll see different output when you run the script from bash directly and from zsh.

The ps -p $$ command from rools's answer will also show useful information about the command the shell used to execute the script.

Related Question