Вопрос по gnu-screen, bash – Bash: получение PID для демонизированного сеанса экрана

7

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

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

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

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

Ваш Ответ

7   ответов
0

Позвольте мне добавить способ получить все PID экрана:

screen -ls | awk '/[0-9]{1,}\./ {print strtonum($1)}'

Поскольку 0-299 - это PID демона в старом ядре, вы можете изменить {1,} на {3,}

Вы можете работать с каждым процессом следующими способами, например выходить из них.

pidList=(screen -ls | awk '/[0-9]{3,}\./ {print strtonum($1)}')
for pid in ${pidList[@]};
do
    screen -X -S $pid quit
done

Вы также можете сделать некоторые другие вещи сscreen -X -S $pid stuff 'command\n'.

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
если у вас есть PID ребенка в $ pid,ps -p $pid -o ppid= покажет PID родителя.
Затем просто используйте PPID PID, который вы уже знаете.
14

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

проса сеанса:

screen -S nameofscreen -Q echo '$PID'

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

2

$ 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 сеанс экрана. Используйте PIDfoo_Monitor сеанс экрана, чтобы получить PIDbash сеанс выполняется в нем путем поиска PPID (родительский 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

Теперь получите только PIDbash сессия:

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

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

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}')
0

$ 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 процессов с этим PID в качестве PPID следующим образом:

$ ps --ppid 19841 -o pid=
19842
3

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

screen -DmS nameofscreen

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

Анализ выходных данных screen -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)

Похожие вопросы