2012-07-03 17 views
5

Nếu tôi bắt đầu phiên màn hình GNU dưới dạng một daemon, làm thế nào tôi có thể lấy lại PID của nó theo lập trình? Tôi không biết làm thế nào phù hợp đầu ra của screen -ls là, vì vậy tôi muốn biết làm thế nào để làm điều này với một trong các hằng số bash, $$, $! hoặc một lựa chọn tốt hơn.Bash: Nhận PID của phiên làm việc daemonized

Tôi đang bắt đầu màn hình với screen -dmS screenname.

Làm cách nào để nhận được PID của màn hình ngay trước hoặc ngay sau khi bắt đầu phiên màn hình?

+0

Có gì sai với 'màn hình -ls'? – sarnold

+0

.. và tại sao bạn không thể thực hiện nó bằng tập lệnh với 'screen-ls'? – sarnold

Trả lời

12

Chương trình này pid cho một màn hình đặt tên 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

tôi nghi ngờ bạn thực sự muốn PID của chương trình chạy bên trong màn hình, mà dường như không phải là dễ dàng có sẵn. (Và không thực sự là một câu hỏi được xác định rõ ràng, vì một quá trình màn hình có thể quản lý nhiều trẻ em - đó là một trong những điều tuyệt vời về màn hình!)

Bạn có thể sử dụng pgrep để tìm quá trình mà PPID là PID màn hình. Hoặc làm điều gì đó như thế này:

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

Sau đó, chỉ cần sử dụng PPID của PID bạn đã biết. –

+1

nếu bạn có PID của trẻ trong $ pid, 'ps -p $ pid -o ppid =' sẽ hiển thị PID của cha mẹ. –

2

bạn có thể sử dụng:

screen -DmS nameofscreen 

mà không ngã ba một quá trình daemon cho phép bạn biết pid.

Phân tích cú pháp đầu ra của màn hình có thể không đáng tin cậy nếu hai phiên màn hình đã được bắt đầu với cùng tên. Một cách khác là không để cho các phiên màn hình ngã ba một quá trình và đặt nó ở chế độ nền tự hỏi:

Ví dụ với một phiên màn hình ban đầu hiện tại:

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

tạo ra một màn hình sử dụng -m -D thay vì -d -m mà không ngã ba một quá trình mới. Đặt nó trong nền và nhận được nó pid. (Sử dụng ngữ nghĩa vỏ posix)

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

Bây giờ có hai màn hình đều có cùng tên:

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

nhưng chúng tôi biết sự khác biệt:

[email protected]% echo $pid 
19431 

và chúng tôi có thể yêu cầu một cách chính xác nó để thoát:

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

bây giờ có chỉ là một bản gốc một lần nữa:

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

Bạn có thể lấy PID của phiên màn hình ở đây như sau:

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

Chúng ta hãy giả sử rằng bạn muốn PID của chương trình đang chạy trong Bash trong phiên foo_Monitor màn hình.Sử dụng PID của phiên foo_Monitor màn hình để có được PID của phiên bash chạy trong nó bằng cách tìm kiếm PPID (Parent PID) cho PID biết:

$ 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 

Bây giờ nhận được chỉ là PID của phiên bash:

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

Bây giờ, chúng tôi muốn quy trình có rằng PID. Chỉ cần tổ các lệnh, và lần này sử dụng -v cờ trên grep bash để có được quá trình đó là không bash:

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

Chỉ cần thay thế 1814 với thực PID hoặc màn hình của bạn phiên:

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

Một cách khác là sử dụng thông số -Q của màn hình để truy vấn phiên:

screen -S nameofscreen -Q echo '$PID' 

Lưu ý rằng điều này cũng sẽ hiển thị PID bên trong phiên màn hình dưới dạng thông báo.

0

Để hoàn thành câu trả lời sarnold của:

$ 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 

... lấy PID của tiến trình với PID này như PPID như sau:

$ ps --ppid 19841 -o pid= 
19842 
Các vấn đề liên quan