3

How would I determine which script is being executed by a process? When I use:

ps -u user

I get the following output:

10005194 26932  0.0  0.0 112700  1544 ?        Ss   Jun03   0:00 -bash
10005194 27117  0.0  0.0 112700  1528 ?        Ss   Apr24   0:00 -bash
10005194 27164  0.0  0.0 112700  2040 ?        Ss   Jun06   0:00 -bash
10005194 27404  0.0  0.0 112700  1544 ?        Ss   May27   0:00 -bash
10005194 27484  0.0  0.0 112700  1528 ?        Ss   Apr23   0:00 -bash
10005194 27531  0.0  0.0 112700  1528 ?        Ss   May22   0:00 -bash
...

There are hundreds of lines. I know that there are a number of scripts that this user is executing, but I would like to narrow down which of the scripts is holding onto threads. Is there a way to do this?

GoldfishGrenade
  • 147
  • 1
  • 5
  • Have you tried `top`? – Wildcard Jun 08 '16 at 01:38
  • yes, but I don't see the pids held by that user. A lot of those bash scripts have finished executing, but the developer has forgotten to exit them, so they remain open threads. – GoldfishGrenade Jun 08 '16 at 01:43
  • Sorry, to clarify, I do see the processes, but the command still says only `bash`. – GoldfishGrenade Jun 08 '16 at 01:45
  • You can use `pstree user | grep bash` to see if bash is running something or just an active shell. – Hesham Ahmed Jun 08 '16 at 01:50
  • Do your scripts start with "#!/usr/bin/env bash"? – fpmurphy Jun 08 '16 at 01:52
  • @HeshamAhmed, `pstree` becomes useless when piped to `grep`. – Wildcard Jun 08 '16 at 02:14
  • 1
    @Wildcard how is `-sshd-+-sshd---bash---ping` useless in finding out what bash is doing? – Hesham Ahmed Jun 08 '16 at 02:18
  • 1
    *A lot of those bash scripts have finished executing, but the developer has forgotten to exit them, so they remain open threads.* This isn't how scripts work. A script exits when it has no more instructions to perform. You can't forget to tell it to exit. Those are interactive shells, note the leading `-`. Also a shell will automatically exit once the thing connected to its STDIN goes away, so something is still holding them open (tmux/screen?). Have you tried running `w` (which will show you TTYs, and how long they've been idle for)? – phemmer Jun 08 '16 at 04:24
  • @fpmurphy1 Yes, the scripts start with #!/usr/bin/env bash – GoldfishGrenade Jun 08 '16 at 06:44
  • this is one of the known problems with using `#!/usr/bin/env`. See http://unix.stackexchange.com/a/238470/7696 – cas Jun 08 '16 at 06:53
  • @Patrick, when I add `exit 0` to the end of one of the scripts, it seemed to stop new ones from accumulated. Why is that? – GoldfishGrenade Jun 08 '16 at 07:03

2 Answers2

0

Use the w (for "wide") option.

From man ps (search for wide):

w Wide output. Use this option twice for unlimited width.

e.g. ps ww -u cas:

$ ps ww -U cas | grep bash
 1350 pts/0    Ss     0:00 -bash
18345 pts/34   S      0:00 /bin/bash /home/cas/bin/myscript.sh
21293 pts/34   Ss+    0:00 bash

The -bash is a login shell.

The plain bash is a non-login interactive shell - the tty pts/34 is the same so you can tell that it is the parent shell (or distant grand-parent) of the myscript.sh bash shell.

Using /usr/env/bin bash prevents you from determining which script is running. Instead you should specify exactly were the bash executable is for the machine you're running on.

GoldfishGrenade
  • 147
  • 1
  • 5
cas
  • 1
  • 7
  • 119
  • 185
  • thanks for the input, but after trying `ps ww -u ` it still returned only the `-bash`. – GoldfishGrenade Jun 08 '16 at 06:47
  • In that case, there weren't any bash scripts running **at the time you ran the `ps`**. Are you sure the scripts you're looking for aren't `#!/bin/sh` scripts? Try `ps ww -u USER | grep -E '/bin/(ba)?sh '` or even `ps ww -u USER | grep -E '/bin/[^ ]*sh '`. – cas Jun 08 '16 at 06:51
  • No, what I meant was that the `ps ww -u` shows many processes running, but they all have the command as just `-bash`. The question asks how to find which script the bash is running. – GoldfishGrenade Jun 08 '16 at 06:54
  • the problem is caused by using `#!/usr/bin/env` in your scripts. there are many good reasons for not doing that, and only one trivial convenience reason for doing so (and even that is solved easier and better with a simple script to change the #! lines as required) – cas Jun 08 '16 at 06:56
  • or, another way of putting it is that your scripts aren't `bash` scripts, they're `/usr/bin/env` scripts which happen to run the bash interpreter. – cas Jun 08 '16 at 06:59
  • It's so confusing. One school of thought is saying "Be portable! use `/usr/bin/env bash`" Another is saying the opposite. So if I use `/usr/bin/env`, it is impossible to determine which script is actually executed? But if I use `/bin/bash`, then I'll be able to see the script in `ps ef`? Do I understand correctly? – GoldfishGrenade Jun 08 '16 at 07:07
  • @GoldfishGrenade, yes that is correct. – fpmurphy Jun 09 '16 at 00:53
0

As @cas suggests, ps can show you some of the information. Adding options can show the command line, which is a step in the right direction. Given this script:

#!/usr/bin/env bash
while true
do
date
sleep 10
done

the suggested ps -ww shows these lines for that process:

  9417 pts/5    00:00:00 bash
  9496 pts/5    00:00:00 sleep

However, ps -fwwl -u $USER shows this:

0 S tom        9417   9416  0  80   0 - 29405 -      18:08 pts/5    00:00:00 bash ./foo
0 S tom        9419   9417  0  80   0 - 28111 -      18:08 pts/5    00:00:00 sleep 10

because I executed ./foo. If I had executed "foo" from my path, of course, there would be no "./". In either case, the actual script which is executed depends upon the value of $PATH as well as the current working directory (when starting the script). For some systems with procfs (such as Linux), it is possible to get that information:

Given all of that, there is enough information (for Linux, at least) for someone to construct a script which would analyze the output of ps to find scripts mentioned with (or without) full pathnames.

Oddly enough, I would have expected lsof to provide the information, because most shells act as if they had an open file descriptor to the script (but I do not see it in a quick check). So analyzing ps and the shell's environment seems the way to go for a complete solution.

Further reading:

Thomas Dickey
  • 75,040
  • 9
  • 171
  • 268