2012-07-03 3 views
5

Se avvio una sessione di schermata GNU come un demone, come faccio a recuperare il PID a livello di programmazione? Non so quanto sia consistente l'output di screen -ls, quindi mi piacerebbe sapere come farlo con una delle costanti di bash, $$, $! o un'alternativa migliore.Bash: acquisizione del PID della sessione schermata demonizzata

Sto avviando la schermata con screen -dmS screenname.

Come si ottiene il PID di uno schermo subito prima o immediatamente dopo l'avvio della sessione dello schermo?

+0

Cosa c'è di sbagliato con '-ls' schermo? – sarnold

+0

.. e perché non puoi farlo con uno script con 'screen -ls'? – sarnold

risposta

12

Questa mostra il PID per uno schermo di nome 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

ho il sospetto che si vuole veramente il PID del programma in esecuzione all'interno dello schermo, che non sembra essere facilmente disponibili. (E non proprio una domanda ben definita, dal momento che una singola schermata può gestire più bambini - questa è una delle grandi cose sullo schermo!)

Si può usare pgrep per trovare un processo il cui PPID è il PID dello schermo. O fare qualcosa di simile:

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

Quindi basta usare il PPID del PID che già conosci. –

+1

se hai il PID del bambino in $ pid, 'ps -p $ pid -o ppid =' mostrerà il PID del genitore. –

2

è possibile utilizzare:

screen -DmS nameofscreen 

che non Fork un processo demone che permette di conoscere il pid.

L'analisi dell'output di screen -ls può non essere affidabile se sono state avviate due sessioni schermo con lo stesso nome. Un altro approccio è quello di non lasciare che la sessione di screen forcella un processo e metterlo in background da soli:

Ad esempio, con una sessione schermata iniziale esistente:

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

creare uno schermo utilizzando -m -D invece di -d -m che non impone un nuovo processo. Mettilo in background e prendi il pid. (Utilizzando la semantica shell POSIX)

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

Ora ci sono due schermi entrambi hanno lo stesso nome:

[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) 

ma sappiamo la differenza:

[email protected]% echo $pid 
19431 

e possiamo con precisione chiederlo per uscire:

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

ora c'è solo quella originale di nuovo:

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

È possibile ottenere il PID delle sessioni di schermo qui in questo modo:

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

Supponiamo che si desidera che il PID del programma in esecuzione in Bash nella sessione dello schermo foo_Monitor.Utilizzare il PID della sessione foo_Monitor schermo per ottenere il PID della sessione bash in esecuzione in essa con la ricerca PPID (Parent PID) per il PID noto:

$ 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 

Ora ottenere solo il PID della sessione bash:

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

Ora vogliamo il processo con del PID. Basta nido i comandi, e questa volta usano la bandiera -v su grep bash per ottenere il processo che non è bash:

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

Basta sostituire 1814 con il vero PID o il vostro schermo sessione:

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

Un altro modo è utilizzando il parametro -Q dello schermo per interrogare la sessione:

screen -S nameofscreen -Q echo '$PID' 

Si noti che questo mostrerà anche il PID all'interno della sessione dello schermo come notifica.

0

Per completare la risposta di 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 

... ottenere i PID di processi con questo PID PPID come segue:

$ ps --ppid 19841 -o pid= 
19842