2012-07-03 3 views
5

Если я запускаю сеанс экрана GNU в качестве демона, как бы программно получить его PID? Я не знаю, насколько согласуется вывод screen -ls, поэтому я хотел бы знать, как это сделать с одной из констант bash, $$, $! или лучшей альтернативой.Bash: Получение PID сеанса демоннизированного экрана

Я запускаю экран с screen -dmS screenname.

Как получить PID экрана прямо перед или сразу после запуска сеанса экрана?

+0

Что случилось с 'экраном -ls'? – sarnold

+0

.. и почему вы не можете сделать это по сценарию с помощью 'screen -ls'? – sarnold

ответ

12

Это шоу Идентификатор для экрана с именем 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

Я подозреваю, что вы действительно хотите PID программы работает внутри экрана, который, кажется, не быть легко доступны. (И не очень четко заданный вопрос, так как один экранный процесс может управлять несколькими детьми - это одна из замечательных особенностей экрана!)

Вы можете использовать pgrep для поиска процесса, PPID которого является идентификатором PID экрана. Или сделать что-то вроде этого:

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

Тогда просто используйте PPID идентификатора PID, который вы уже знаете. –

+1

, если у вас есть PID ребенка в $ pid, 'ps -p $ pid -o ppid =' покажет родительский PID. –

2

вы можете использовать:

screen -DmS nameofscreen 

, не раскошелиться процесс демон, позволяющий вам знать PID.

Анализ вывода экрана -ls может быть ненадежным, если два сеанса экрана были запущены с тем же именем. Другой подход заключается, чтобы не допустить на экране сеанса вилки процесс и поставить его на фоне себя:

Например с существующей начальной сессии экрана:

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

создать экран, используя -D -m вместо -d -m, который не вызывает нового процесса. Положите его в фоновом режиме и получите его pid. (Использование Posix семантики оболочки)

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

В настоящее время существует два экрана оба имеют одинаковое имя:

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

но мы знаем разницу:

[email protected]% echo $pid 
19431 

и мы можем точно задать его для прекращения деятельности:

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

теперь есть только оригинал один раз:

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

Вы можете получить PID сессий экрана здесь, как так:

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

Давайте предположим, что вы хотите PID программы работает в Bash в сеансе экрана foo_Monitor.Используйте PID сеанса на foo_Monitor экрана, чтобы получить PID сессии bash работает в ней с помощью функции поиска идентификаторы PPID (Parent PID) для известного 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 

Теперь получить только PID сессии bash:

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

Теперь мы хотим, чтобы процесс был с , что PID. Просто гнездо команды, и на этот раз использовать -v флаг на grep bash, чтобы получить процесс, который не Баш:

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

Просто замените 1814 с реальным PID или ваш экран сессии:

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

Другой способ использует параметр -Q экрана для запроса сеанса:

screen -S nameofscreen -Q echo '$PID' 

Обратите внимание, что это также отображает PID в сеансе экрана в качестве уведомления.

0

Чтобы завершить ответ 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 

... получить ИДП процессов с этим PID, как PPID следующим образом:

$ ps --ppid 19841 -o pid= 
19842 
Смежные вопросы