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
  • 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
  • 434,908