Bash:获取守护屏幕会话的 PID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11320782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:40:08  来源:igfitidea点击:

Bash: Getting PID of daemonized screen session

bashgnu-screen

提问by hexacyanide

If I start a GNU screen session as a daemon, how would I retrieve its PID programmatically? I don't know how consistent the output of screen -lsis, so I'd like to know how to do this with one of bash's constants, $$, $!or a better alternative.

如果我将 GNU 屏幕会话作为守护程序启动,我将如何以编程方式检索其 PID?我不知道如何输出一致 screen -ls的,所以我想知道如何使用bash的常量之一,做到这一点$$$!还是更好的选择。

I am starting the screen with screen -dmS screenname.

我用screen -dmS screenname.

How would I get the PID of a screen right before or immediately after starting the screen session?

如何在开始屏幕会话之前或之后立即获取屏幕的 PID?

回答by sarnold

This show the pid for a screen named nameofscreen:

这显示了名为 的屏幕的 pid 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()}'
19841
$ 

回答by fess .

you can use:

您可以使用:

screen -DmS nameofscreen

which does not fork a daemon process allowing you to know the pid.

它不会分叉守护进程,让您知道 pid。

Parsing the output of screen -ls can be unreliable if two screen sessions have been started with the same name. Another approach is to not let the screen session fork a process and put it in the background yourself:

如果两个 screen 会话以相同的名称启动,则解析 screen -ls 的输出可能不可靠。另一种方法是不要让屏幕会话派生一个进程并自己将其置于后台:

For example with an existing initial screen session:

例如,对于现有的初始屏幕会话:

fess@hostname-1065% screen -ls
There is a screen on:
        19180.nameofscreen    (01/15/2013 10:11:02 AM)        (Detached)

create a screen using -D -m instead of -d -m which does not fork a new process. Put it in the background and get it's pid. (Using posix shell semantics)

使用 -D -m 而不是 -d -m 创建一个屏幕,它不会分叉新进程。把它放在后台并得到它的pid。(使用 posix shell 语义)

fess@hostname-1066% screen -DmS nameofscreen & 
[3] 19431
fess@hostname-1067% pid=$! 

Now there are two screens both have the same name:

现在有两个屏幕都具有相同的名称:

fess@hostname-1068% 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)

but we know the difference:

但我们知道区别:

fess@hostname-1069% echo $pid
19431

and we can accurately ask it to quit:

我们可以准确地要求它退出:

fess@hostname-1070% screen -S $pid.nameofscreen -X quit
[3]  - done       screen -DmS nameofscreen

now there's just the original one again:

现在又只有原来的了:

fess@hostname-1071% screen -ls 
There is a screen on:
        19180.nameofscreen    (01/15/2013 10:11:02 AM)        (Detached)

回答by dotancohen

You can get the PID of the screen sessions here like so:

您可以在此处获取屏幕会话的 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.

Let us suppose that you want the PID of the program running in Bash in the foo_Monitorscreen session. Use the PID of the foo_Monitorscreen session to get the PID of the bashsession running in it by searching PPIDs (Parent PID) for the known PID:

让我们假设您想要在foo_Monitor屏幕会话中在 Bash 中运行的程序的 PID 。使用foo_Monitorscreen 会话的 PIDbash通过搜索已知 PID 的 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

Now get just the PID of the bashsession:

现在只获取bash会话的 PID :

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

Now we want the process with thatPID. Just nest the commands, and this time use the -vflag on grep bashto get the process that is notbash:

现在我们想要具有PID的进程。只需嵌套命令,这次使用-v标志 ongrep bash来获取不是bash的进程:

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

Just replace 1814 with the real PID or your screen session:

只需将 1814 替换为真实的 PID 或您的屏幕会话:

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

回答by Alan Curry

I suspect you really want the PID of the program running inside screen, which doesn't seem to be easily available. (And not really a well-defined question, since a single screen process can manage multiple children - that's one of the great things about screen!)

我怀疑您真的想要在屏幕内运行的程序的 PID,这似乎不容易获得。(并不是一个真正定义明确的问题,因为单个屏幕进程可以管理多个子项 - 这是屏幕的一大优点!)

You could use pgrep to find a process whose PPID is the screen PID. Or do something like this:

您可以使用 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

回答by Nagisa

This answer is inspired by @sarnold.

这个答案的灵感来自@sarnold。

Let me add a way to get all the screen PID:

让我添加一种获取所有屏幕 PID 的方法:

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

Since 0-299 is the PID of the daemon in the old kernel, you can change {1,} to {3,}

由于 0-299 是旧内核中守护进程的 PID,因此您可以将 {1,} 更改为 {3,}

You can operate on each process in the following ways, such as exiting them.

您可以通过以下方式对每个进程进行操作,例如退出它们。

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

You can also do some other things with screen -X -S $pid stuff 'command\n'.

您还可以使用screen -X -S $pid stuff 'command\n'.

回答by Lars Schillingmann

Another way is using screen's -Q parameter for querying the session:

另一种方法是使用 screen 的 -Q 参数来查询会话:

screen -S nameofscreen -Q echo '$PID'

Note that this will also display the PID inside the screen session as a notification.

请注意,这还将在屏幕会话中显示 PID 作为通知。

回答by user3093815

To complete sarnold's answer:

要完成 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()}'
19841

... get the PIDs of processes with this PID as PPID as follows:

...获取具有此 PID 作为 PPID 的进程的 PID,如下所示:

$ ps --ppid 19841 -o pid=
19842