Is there a difference in behaviours with respect to the flags passed to the script on the shebang line vs. using the set
builtin?
For example:
#!/bin/bash -e
# do stuff
vs.
#!/bin/bash
set -e
# do stuff
(The question is not specific to -e
flag but in general for any such flags).
Obviously the set [flags]
is effective only from the point it's set. But are there any other differences in functionality/behaviour?
Is behaviour same in a POSIX shell, too?
1) tells bash to exit under certain conditions (which may apply to your script). If that is the case, " set -xe " might print more of the trace before exiting than " set -e " followed by " set -x ".
What is the shebang? The shebang is a special character sequence in a script file that specifies which program should be called to run the script. The shebang is always on the first line of the file, and is composed of the characters #! followed by the path to the interpreter program.
The shebang is only mandatory for those scripts, which shall be executed by the operating system in the same way as binary executables. If you source in another script, then the shebang is ignored. On the other hand. IF a script is supposed to be sourced, then it is convention to NOT put any shebang at the start.
by Taimoor Mohsin. In Bash, the set command allows you to manage certain flags and characteristics to influence how your bash scripts behave. These controls ensure that your scripts follow the correct path and that Bash's peculiar behavior does not cause difficulties.
are there any other differences in functionality/behaviour?
When your file has executable permissions and is executed, then the shebang line is parsed by the kernel.
When your file is executed under the shell like bash ./script.sh
then the shebang is just a comment. So it will be ignored, and your script will be run with whatever the callers flags are. Putting your flags after the shebang will make sure proper flags are set in your scripts in either case.
The shebang is parsed by kernel. That basically means that the behavior differs from kernel to kernel, from operating system to operating system. Some operating systems didn't handle arguments in shebang at all and ignored all the arguments. Some kernels parse for example #!/bin/sh -a -b
as execl("/bin/sh", "-a -b")
some as execl("/bin/sh", "-a", "-b")
. The parsing of the shebang line to executable and arguments is done by some other code different that your shell. Sometimes if there is a space after #!
like #! /bin/sh
utilities don't recognize it as a valid shebang. There's even a recent linux kernel regression with too long shebang line.
The behavior of how shebang is interpreted differs between systems, so you can't be certain, so it's best to set
options after the shebang.
Is behaviour same in a POSIX shell, too?
A POSIX shell doesn't (have to) interpret your shebang. If you are asking if executing sh -e
and set -e
has the same behavior in posix shell, then yes, the option -e
on command line has the same behavior as set -e
.
I couldn't find a specification of shebang line nor how should it be interpreted in posix specification. I can see in execve documentation:
Another way that some historical implementations handle shell scripts is by recognizing the first two bytes of the file as the character string "#!" and using the remainder of the first line of the file as the name of the command interpreter to execute.
Those "historical implementations" seem to be very widely used still today.
The shebang line is parsed by the kernel after exec*
calls. But when you are doing sh <script>
or popen
or system
the shell can (but doesn't have to) interpret the shebang line by itself as a extension and not rely on kernel implementation, from posix:
Shell Introduction
- The shell reads its input from a file (see sh), from the
−c
option or from thesystem()
andpopen()
functions defined in the System Interfaces volume of POSIX.1-200x. If the first line of a file of shell commands starts with the characters"#!",the results are unspecified.
As for bash, it looks like bash first tries execve, then if it can't find the reason why kernel failed to run the executable, if the file has a shebang, then it parses shebang on its own to find out the interpreter.
Some operating systems may disallow or limit the use of arguments in the shebang. No such limit would apply to a set
command in the script itself.
The manpage states that "-e" has different behaviour depending on POSIX mode or not. Other than that, I have never noticed a difference between setting parameters and extending shebang. Why are you asking this question?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With