Bash Shebang – Actual Command Executed with Same Arguments

bashcommand lineshebang

From bash manual about shebang

Most versions of Unix make this a part of the operating system’s
command execution mechanism. If the first line of a script begins with
the two characters‘ #!’, the remainder of the line specifies an
interpreter for the program. Thus, you can specify Bash, awk, Perl, or
some other interpreter and write the rest of the script file in that
language.

The arguments to the interpreter consist of a single optional argument following the interpreter name on the first line of the
script file, followed by the name of the script file, followed by
the rest of the arguments. Bash will perform this action on operating systems that do not handle it themselves. Note that some
older versions of Unix limit the interpreter name and argument to a
maximum of 32 characters.

Does "a optional argument" mean an argument to an option, or an argument which may be there or might not be?

Why "a single optional argument"? does it not allow multiple "optional arguments"?

If a script looks like

#! /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2

...

when I run the script in bash as

$ myscript arg1 arg2 arg3

what is the actual command being executed in bash? Is it

$ /path/to/interpreter --opt1 opt1-arg --opt2 opt2-arg --opt3 nonopt-arg1 nonopt-arg2 myscript arg1 arg2 arg3

Thanks.

Best Answer

The arguments to the interpreter in this case are the arguments constructed after interpretation of the shebang line, combining the shebang line with the script name and its command-line arguments.

Thus, an AWK script starting with

#! /usr/bin/awk -f

named myscript and called as

./myscript file1 file2

results in the actual arguments

/usr/bin/awk -f ./myscript file1 file2

The single optional argument is -f in this case. Not all interpreters need one (see /bin/sh for example), and many systems only allow at most one (so your shebang line won’t work as you expect it to). The argument can contain spaces though; the whole content of the shebang line after the interpreter is passed as a single argument.

To experiment with shebang lines, you can use #! /bin/echo (although that doesn’t help distinguish arguments when there are spaces involved).

See How programs get run for a more detailed explanation of how shebang lines are processed (on Linux).