Get PID of process started in screen by su

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.


Solution 1:

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.

Solution 2:

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.

Solution 3:

If you want the PID of the process running in screen, I answered that in another question on 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 of your screen session:

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

Solution 4:

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!