3

I have written a simple shell script as follows:

#!/bin/bash
sleep 90

After running this shell I run pstree in a separate shell to see the process tree structure.

Here is what I see

-gnome-terminal-+-bash---sleepy.sh---sleep

I was expecting this to be like

-gnome-terminal-+-bash---bash---sleep

Why is a shell script being represented as a process by pstree? The ps command correctly shows the command being executed as

10150  8771  0 08:13 pts/1    00:00:00 /bin/bash ./sleepy.sh

Here the process is bash and sleepy.sh is its argument (this makes sense to me). In my view a process has to be an Executable Linkable Format binary (ELF). Bash is an ELF executable but a shell script is not and hence I think pstree should not be showing it as such?

Mingye Wang
  • 1,181
  • 9
  • 23
  • Because it's a process. – Ipor Sircer Nov 15 '16 at 13:07
  • That's not what the questioner is asking, Ipor Sircer. The title is badly phrased. It would be better to read something along the lines of _Why is pstree showing the name of my script instead of the name of the shell that is interpreting it?_ – JdeBP Nov 15 '16 at 13:09
  • Did you run this script by name, or did you run this script using 'bash sleepy.sh'? – Andy Dalton Nov 15 '16 at 14:35

1 Answers1

6

pstree retrieves the process name from /proc/<pid>/stat. This is whatever was given to the kernel via execve(2)'s first parameter; see proc(5) and What exactly happens when I execute a file in my shell? for details. You'll see from the latter that the kernel can run shell scripts directly (and many other "binaries" — see How is Mono magical?), but the shell also steps in in some cases.

Thus, if you run

./sleepy.sh

with a shebang line at the start of the script, you'll see sleepy.sh in pstree's output because that's what the shell asks the kernel to run. If instead you run

sh ./sleepy.sh

you'll see sh in pstree's output.

ps -f or ps u (and pstree -a) read /proc/<pid>/cmdline instead to retrieve the command line, which is different — it's the argv parameter given to the execve system call. When running a shell script with a shebang, this is changed to include the shebang, which is no doubt why in your case ps shows

/bin/bash ./sleepy.sh

(see How programs get run for lots more on this).

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164