2012-07-03 8 views
5

Si comienzo una sesión de pantalla GNU como daemon, ¿cómo recuperaré su PID mediante programación? No sé qué tan consistente es la salida de screen -ls, así que me gustaría saber cómo hacer esto con una de las constantes de bash, $$, $! o una alternativa mejor.Bash: Obtención del PID de la sesión de pantalla daemonizada

Estoy comenzando la pantalla con screen -dmS screenname.

¿Cómo obtendría el PID de una pantalla justo antes o inmediatamente después de iniciar la sesión de pantalla?

+0

¿Qué pasa con '-ls' pantalla? – sarnold

+0

.. y ¿por qué no puedes hacerlo por script con 'screen -ls'? – sarnold

Respuesta

12

Este espectáculo el PID para una pantalla llamada nameofscreen:

$ screen -ls 
There are screens on: 
    19898.otherscreen (07/03/2012 05:50:45 PM) (Detached) 
    19841.nameofscreen (07/03/2012 05:50:23 PM) (Detached) 
2 Sockets in /var/run/screen/S-sarnold. 

$ screen -ls | awk '/\.nameofscreen\t/ {print strtonum($1)}' 
19841 
$ 
2

sospecho que realmente quiere el PID del programa que se ejecuta dentro de la pantalla, lo que no parece que sea fácilmente disponible. (Y no es realmente una pregunta bien definida, ya que un solo proceso de pantalla puede administrar varios hijos: ¡esa es una de las mejores cosas de la pantalla!)

Puede usar pgrep para buscar un proceso cuyo PPID es el PID de la pantalla. O hacer algo como esto:

rm mypidfile 
screen -dmS blah sh -c 'echo $$ > mypidfile ; exec sh' 
# the write to mypidfile is happening in the background, so wait it to show up 
while [ ! -s mypidfile ]; do sleep 1; done 
pid=`cat mypidfile` 
# $pid is now the PID of the shell that was exec'ed inside screen 
+0

Luego solo use el PPID del PID que ya conoce. –

+1

si tiene el PID del niño en $ pid, 'ps -p $ pid -o ppid =' mostrará el PID del padre. –

2

que puede utilizar:

screen -DmS nameofscreen 

la que no se bifurca un proceso demonio que le permite saber el PID.

Analizar la salida de las pantallas -ls puede no ser confiable si se han iniciado dos sesiones de pantalla con el mismo nombre. Otro enfoque es no dejar que la sesión de pantalla tenedor un proceso y ponerlo en el fondo de sí mismo:

Por ejemplo, con una sesión de pantalla inicial existente:

[email protected]% screen -ls 
There is a screen on: 
     19180.nameofscreen (01/15/2013 10:11:02 AM)  (Detached) 

crear una pantalla utilizando -m -D en lugar de -d-m que no bifurca un nuevo proceso. Póngalo en segundo plano y obtenga su pid. (El uso de la semántica shell POSIX)

[email protected]% screen -DmS nameofscreen & 
[3] 19431 
[email protected]% pid=$! 

Ahora hay dos pantallas ambas tienen el mismo nombre:

[email protected]% screen -ls 
There are screens on: 
     19431.nameofscreen (01/15/2013 10:53:31 AM)  (Detached) 
     19180.nameofscreen (01/15/2013 10:11:02 AM)  (Detached) 

pero sabemos la diferencia:

[email protected]% echo $pid 
19431 

y podemos preguntar con precisión para salir:

[email protected]% screen -S $pid.nameofscreen -X quit 
[3] - done  screen -DmS nameofscreen 

ahora no sólo el original de nuevo:

[email protected]% screen -ls 
There is a screen on: 
     19180.nameofscreen (01/15/2013 10:11:02 AM)  (Detached) 
2

Puede obtener el PID de las sesiones de pantalla aquí, así:

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

Supongamos que desea que el PID del programa que se ejecuta en Bash en la sesión de pantalla foo_Monitor.Utilizar el PID de la sesión foo_Monitor pantalla para obtener el PID de la sesión bash correr en ella mediante la búsqueda PPID (Padre PID) para el PID conocido:

$ 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 

Ahora obtener sólo el PID de la sesión bash:

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

Ahora queremos que el proceso con que PID. Sólo nido de los comandos, y esta vez utilizan la bandera -v en grep bash para que el proceso que es no bash:

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

Basta con sustituir 1814 con el PID real o la pantalla de sesión:

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

Otra forma es utilizar el parámetro -Q de pantalla para la consulta de la sesión:

screen -S nameofscreen -Q echo '$PID' 

Tenga en cuenta que esto también mostrará el PID dentro de la sesión de la pantalla como una notificación.

0

Para completar la respuesta de sarnold:

$ screen -ls 
There are screens on: 
    19898.otherscreen (07/03/2012 05:50:45 PM) (Detached) 
    19841.nameofscreen (07/03/2012 05:50:23 PM) (Detached) 
2 Sockets in /var/run/screen/S-sarnold. 

$ screen -ls | awk '/\.nameofscreen\t/ {print strtonum($1)}' 
19841 

... consiguen los PID de los procesos con este PID como PPID de la siguiente manera:

$ ps --ppid 19841 -o pid= 
19842 
Cuestiones relacionadas