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?

  • 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.

cas
  • 78,579
  • thanks for the input, but after trying ps ww -u <user> 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
  • 76,765