My OS: Ubuntu 18.04.5 LTS
I use tracing for troubleshooting a script. I've notice different behaviors in the tracing depending on how I set it up. I would like to understand why it behaves this way.
I normally activate tracing using set -x
in my script where I need the tracing to take place. However the Prompt String PS4 ("+ " by default) seems to "duplicate" itself.
If I active tracing in the shebang #! line, PS4 is only printed once.
Similarly, if I call bash
directly for running my script, and specifying -x
in the command line, PS4 is also only printed once.
Why is set -x
behaving differently in the first example ? I guess there is something fundamental about the shell which I am not getting here...
The distinction here is not where you place the
-x
, it's whether you specify a shell to use (either via a shebang, or by invoking the script explicitly withbash -x
).According to
man bash
,PS4
:however it is not forthcoming about what "levels of indirection" means in this context.
When you try to execute a text file without specifying what interpreter to use, the system call to
execve
fails withENOEXEC (Exec format error)
. What happens next depends on the shell from which you are trying to execute it, as described here:In particular, if the invoking shell is
bash
, then the script appears to get executed directly by the invoking shell: this appears to be the "indirection" mentioned in the manual:Note that the
bash -c
in the strace call here takes the place of your interactive shell, rather than of thebash -x
that you used in your last example.As soon as we add a shebang, ex.:
then (regardless of whether
-x
is invoked usingset
or otherwise), thenexecve
succeeds and the script is executed in its own shell, without "indirection":If you'd invoked the no-shebang script from
dash
for example, the behavior would be different: after the initial failedexecve
, it would haveexecve
'd/bin/sh
to execute the script: