Does that mean the procces that was actually run is /bin/bash and everything after that was only passed to it as arguments(Procces: /bin/bash args that it got: ./sleeper.sh 10)??
That's exactly the case. When you run a script like this: ./script
, the program loader parses the script, looking for a shebang that will tell it how to run that script. Shebangs are needed to differentiate, say, a Python script from a Bash script, or from a Perl script. Such scripts are actually executed by their respective interpreters, which are usually /bin/python
, /bin/bash
, /bin/perl
, and that's why you see it listed as /bin/bash ./sleeper 10
rather than ./sleeper.sh 10
.
For example, say ./script
looks like this:
#!/bin/sh
echo yo
Running it with ./script
will cause the system to spawn /bin/sh ./script
. (Anecdote: because of how it works, some shebangs include also command line parameters on its own such as #!/usr/bin/perl -T
, which will cause the system to spawn your script as /usr/bin/perl -T x
).
As for why the script sees ./sleeper.sh 10
rather than /bin/bash ./sleeper.sh 10
- it's just how Bash (and other interpreters) works. The shebang expansion is visible to everyone, including Bash. Hence ps ux
will show /bin/bash ./sleeper.sh 10
. However, it would make little sense for your script to know exact specific combination of Bash flags and Bash path it was invoked with, so Bash strips these away and passes only relevant command line. Bash tries to make that command line consistent with general command line rules, meaning the first argument to your script will be usually the path to your script (caveats), and the rest of the arguments are the arguments passed to your script.
Seeing all of this in action
./test
:
#!/bin/bash -i
echo $BASH_ARGV
- Running it as
./test
prints nothing. The process is spawned as /bin/bash -i ./test
.
- Running it as
./test x y
prints x y
. The process is spawned as /bin/bash -i ./test x y
.
Suggestion
It's widely recommended to omit .sh
, .py
, .pl
etc. extensions from executable files.