2012-07-03 36 views
5

如果我作爲守護進程啓動一個GNU屏幕會話,我將如何以編程方式檢索其PID?我不知道screen -ls的輸出如何一致,所以我想知道如何用bash的常量$$,$!或更好的替代方法做到這一點。Bash:獲得守護進程屏幕會話的PID

我以screen -dmS screenname開始屏幕。

如何在開始屏幕會話之前或之後立即獲取屏幕的PID?

+0

出了什麼問題'屏幕-ls'? – sarnold

+0

..爲什麼你不能用'screen -ls'腳本來做到這一點? – sarnold

回答

12

這個節目的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($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

然後只使用您已知的PID的PPID。 –

+1

如果您在$ pid中擁有孩子的PID,則'ps -p $ pid -o ppid ='將顯示父母的PID。 –

2

你可以使用:

screen -DmS nameofscreen 

不fork一個守護進程,讓您知道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搜索PPIDs(父PID),以獲得在其上運行的bash會議的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 

現在得到公正的bash會議的PID:

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

現在我們想要那個進程 PID。就巢的命令,這時候使用上grep bash-v標誌,以獲得過程,是慶典:

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

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

剛剛與實際PID或您的屏幕會話取代1814

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得到進程的PID爲PPID如下:

$ ps --ppid 19841 -o pid= 
19842