20

Either I am not able to phrase my search correctly or the answer is not easy to find!, but I am trying to figure out how to list all of my background task PIDs. For example:

So far I have found that to list the last PID we use:

$!

But now I want to list the PID of the task before that (if one exists), but I can't find how to do that. Utlimatly I want to list all my background task PIDs.

I know we can also find last job ID with:

%% (last job in list)
%1 (first job in list)
%2 (second job in list)

But the same does not seem to work for process id?

Thanks all :)

code_fodder
  • 15,263
  • 17
  • 90
  • 167

4 Answers4

34

Use ps S. For example:

$ vim &
[1] 8263
$ ipython &
[2] 8264
$ ps S
 PID TTY      STAT   TIME COMMAND
 3082 pts/0    Ss     0:00 bash
 3137 pts/0    Sl+    0:00 python /usr/bin/ipython
 8207 pts/2    Ss     0:00 bash
 8263 pts/2    T      0:00 vim
 8264 pts/2    Tl     0:00 python /usr/bin/ipython
 8284 pts/2    Tl     0:00 python /usr/bin/ipython
 8355 pts/2    R+     0:00 ps S

If you want get PIDs use below:

$ ps S | awk '{print  $  1 }' | grep -E '[0-9]'
3082
3137
8207
8263
8264
8284
8357
8358
835

Also you can use jobs -l But it show background processes only for current session.

Michael Kazarian
  • 4,376
  • 1
  • 21
  • 25
  • 2
    `ps S` gives a huge list in my shell (also children from sibling shells etc.). But `ps --ppid $$` works fine for me – Alfe Sep 18 '13 at 09:11
  • 1
    I took this idea, which is really cool thanks (+1) and modified it to match my puposes a little closer: `list=\`ps S | grep "search-string" | awk '{print $ 1}'\``. Now I can use the result stored in $list to loop through these tasks : ) – code_fodder Sep 18 '13 at 09:40
  • @code_fodder I also have thinked what you want `grep "search-string"` but you wrote only PID. – Michael Kazarian Sep 18 '13 at 09:45
  • @MichaelKazarian yes I know :), I use the grep before the awk only as a filter for me to find the PIDs I want from their "long" descriptions. Its basically the same as what you did, but if you do the "awk" first then we only have the raw PIDs to string search. Still, its just minor difference, thanks! – code_fodder Sep 18 '13 at 09:48
  • Your command line is unnecessarily long. `awk` does everything `grep` does, so `ps S | awk '/[0-9]/{print $1}'` does the same thing. – ghoti Sep 18 '13 at 13:47
  • @Alfe - the `--ppid` option may work on GNU ps, but it doesn't work in FreeBSD, OSX, Solaris, etc. This question isn't limited to Linux. – ghoti Sep 18 '13 at 13:48
  • All true. Answers here shouldn't be limited to Linux only, and `--ppid` works for me ;-) – Alfe Sep 18 '13 at 13:50
15

But the same does not seem to work for process id?

You can try jobs -l or -p. The -l and -p switches cause the jobs command to also output process IDs.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • This definatley works...thanks :), but I want to be able to access them individually like you can with the %1, %2 command. Is there such a way? – code_fodder Sep 18 '13 at 09:02
  • @code_fodder You might want to pipe the output of `jobs` through a `while read` loop and get each line. – cnicutar Sep 18 '13 at 09:03
  • jobs -l is not working if issued in another console/terminal/shell as the jobs command only shows jobs running in current shell session. – Vic VKh Oct 06 '20 at 09:23
5

In bash, as in tcsh, the command you probably want is jobs -l (for Long).

[ghoti@pc ~]$ sleep 300 &
[1] 33811
[ghoti@pc ~]$ sleep 301 &
[2] 33812
[ghoti@pc ~]$ sleep 302 &
[3] 33813
[ghoti@pc ~]$ jobs -l
[1]- 33811 Running                 sleep 300 &
[2]- 33812 Running                 sleep 301 &
[3]+ 33813 Running                 sleep 302 &
[ghoti@pc ~]$ 
ghoti
  • 45,319
  • 8
  • 65
  • 104
  • This definatley works...thanks :), but I want to be able to access them individually like you can with the %1, %2 command. Is there such a way? (same comment as for cnicutar) – code_fodder Sep 18 '13 at 09:02
1

If you also want to see your child processes which aren't handled as a job by the shell anymore (e. g. because you disowned them deliberately or similar), then you can use this to find all processes which have you as their parent:

grep "PPid:.*$$" /proc/[0-9]*/status | cut -d/ -f3

Also

ps --ppid $$

can be of use. (Credits to @Michael Kazarian who also has an answer here.)

Alfe
  • 56,346
  • 20
  • 107
  • 159
  • Thanks for that also works, but I prefer the slightly simpler syntax in Michaels post. +1 for good answer/comments though – code_fodder Sep 18 '13 at 09:42
  • My OS doesn't mount `/proc` by default, but if I do mount it, `/proc/[0-9]*/status` does not contain any lines containing `Ppid:`. If I want the parent pid of my shell, I use: `ps Oppid $$` to add it to ps' output, or `ps oppid $$` to display only the ppid. – ghoti Sep 18 '13 at 13:51
  • 1
    Yeah. Besides Posix (which doesn't seem to cover this issue) there isn't really a standard to cling to, so writing stuff to be compatible is hard in shell. Better use Python, C or similar then. – Alfe Sep 18 '13 at 13:55