Get PID of process started in screen by su

1

i have a simple script that starts quassel-core in a screen session as different user! The script is:

#!/bin/sh
su ircc -c 'screen -dmS quassel /home/ircc/quassel/quassel-core'

I want to start and stop this in an debian init.d script using start-stop-daemon What is the best way to get the PID of quassel-core (or of the screen, that should work too) and store it in a file? At the moment i use:

pidof quassel-core > /var/run/quasselcore.pid

but that will fail if some other user starts quassel-core.

Josef says Reinstate Monica

Posted 2012-05-14T16:08:12.830

Reputation: 1 230

pgrep -u ircc -f quassel-core – PsyKzz – 2015-01-11T00:25:52.243

Answers

3

It seems like you are happy just to kill a named screen session belonging to your user, and not really interested in the pid. In that case, with a screen named "quassel", you can run

screen -S quassel -X quit

which as per the manual will

Kill all windows and terminate screen.

Only screens owned by you are affected.

Daniel Andersson

Posted 2012-05-14T16:08:12.830

Reputation: 20 465

3

In the procps package (or something similarly named, depending on distribution) you can find pgrep:

pgrep looks through the currently running processes and lists the process IDs which matches the selection criteria to stdout.

So in your case:

pgrep -u josef quassel-core

should give you a list of the process IDs belonging to currently running quassel-core processes started by the josef user.

In the package you also get pkill which kills a process based on a similar search process, so you wouldn't really need a pid file if this is all you are going to use it for.


All that said: if you use start-stop-daemon, you can use the --pidfile switch to start the process. See man start-stop-daemon for usage.

Daniel Andersson

Posted 2012-05-14T16:08:12.830

Reputation: 20 465

the --pidfile option doesn't work, because it will store the pid of the su process which will instantly exit after running screen! – Josef says Reinstate Monica – 2015-01-12T10:22:49.630

+1 This is a good way to go, similar method using ps: ps -U <user> | grep <process_name> | awk '{print $1}' – MaQleod – 2012-05-14T16:32:18.523

1

After some more trying, here is my own solution:

screen -list | grep quassel | cut -f1 -d'.' | sed 's/\W//g'

It reads the pid of the screen with the name "quassel" Seems to be the safest way to me.

Thanks also to Daniel Andersson, this should work too.

start-stop-daemons --pidfile is of no use, because it doesn't create the pidfile! With -m it would store the pid of the screen started, but screen seems to fork itself on start, so the pid changes!

Josef says Reinstate Monica

Posted 2012-05-14T16:08:12.830

Reputation: 1 230

1screen -list | awk '/quassel/{print substr($1,0,index($1,".")-1)}' is fewer forks and "nicer". But see separate answer if you just want to kill a named screen session. – Daniel Andersson – 2012-05-15T06:36:29.523

0

Would this work for you?

ps -ef | grep quassel-cor[e] | awk '{print $2}' > /var/run/quasselcore.pid

This assumes that there is only one such process running. If that is not true you need to further refine your grep.

johnshen64

Posted 2012-05-14T16:08:12.830

Reputation: 4 399

Instead of grep you could use awk '/quassel-core/{print $2}' directly.psis not really meant to be used for processing like this, though; it is more of a presentation layer and can give unwanted results when trying to be processed (such as including the matching process itself among the matches). Better is to use a tool designed for searching through/proc` in a more strict manner. In this case this is noticed since Josef wants to match on user name as well, and the matching soon gets tedious this way. – Daniel Andersson – 2012-05-14T16:25:57.077

0

If you want the PID of the process running in screen, I answered that in another question on this Stack Overflow. Here is the contents of that answer:

You can get the PID of the screen sessions here like so:

$ screen -ls
There are screens on:
        1934.foo_Server         (01/25/15 15:26:01)     (Detached)
        1876.foo_Webserver      (01/25/15 15:25:37)     (Detached)
        1814.foo_Monitor        (01/25/15 15:25:13)     (Detached)
3 Sockets in /var/run/screen/S-ubuntu.

Let us suppose that you want the PID of the program running in Bash in the foo_Monitor screen session. Use the PID of the foo_Monitor screen session to get the PID of the bash session running in it by searching PPIDs (Parent PID) for the known PID:

$ ps -el | grep 1814 | grep bash
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  1815  1814  0  80   0 -  5520 wait   pts/1    00:00:00 bash

Now get just the PID of the bash session:

$ ps -el | grep 1814 | grep bash | awk '{print $4}'
1815

Now we want the process with that PID. Just nest the commands, and this time use the -v flag on grep bash to get the process that is not bash:

echo $(ps -el | grep $(ps -el | grep 1814 | grep bash | awk '{print $4}') | grep -v bash | awk '{print $4}')
23869

Just replace 1814 with the real PID or your screen session:

echo $(ps -el | grep $(ps -el | grep SCREEN_SESSION_PID | grep bash | awk '{print $4}') | grep -v bash | awk '{print $4}')

dotancohen

Posted 2012-05-14T16:08:12.830

Reputation: 9 798