Làm thế nào để tôi nhận được các cổng mà quá trình đang lắng nghe khi sử dụng python? Các pid của quá trình này được biết đến.Làm thế nào để có được cổng mà một quá trình lắng nghe?
Trả lời
Bạn có thể sử dụng netstat -lnp
, cột cuối cùng sẽ chứa tên pid và quá trình. Trong Python bạn có thể phân tích đầu ra của lệnh này.
Nếu bạn không muốn phân tích đầu ra của một chương trình như netstat hoặc lsof, bạn có thể duyệt qua hệ thống tập tin/proc và tìm tài liệu trên các tệp bên trong. /proc/<pid>/net/tcp
có thể đặc biệt thú vị với bạn. Tất nhiên, định dạng của các tệp đó có thể thay đổi giữa các bản phát hành hạt nhân, do đó, đầu ra lệnh phân tích cú pháp thường được coi là đáng tin cậy hơn.
Có hai phần câu trả lời của tôi:
1. Lấy thông tin trong vỏ
Đối với phần đầu tiên, netstat
sẽ làm việc, nhưng tôi thích sử dụng lsof
, vì nó có thể được sử dụng để trích xuất một danh sách nhiều thông tin và súc tích hơn. Các tùy chọn chính xác để sử dụng có thể thay đổi dựa trên hệ điều hành, hạt nhân và biên dịch của bạn lựa chọn, nhưng tôi tin rằng bạn muốn một cái gì đó như thế này:
lsof -a -p23819 -i4
đâu 23819
là PID bạn đang chọn cho, và i4
biểu thị tất cả các ổ cắm IPv4 (mặc dù bạn có thể muốn i6
cho IPv6, như trường hợp có thể). Từ đó, bạn có thể đi qua grep để chỉ chọn các ổ cắm nghe.
lsof -a -p23819 -i4 | grep LISTEN
(Trong lsof
phiên bản 4,82, bạn có thể bổ sung sử dụng -sTCP:LISTEN
cờ thay vì grep
để chọn ổ cắm nghe, mặc dù tùy chọn này dường như không được cung cấp trở lại trong phiên bản 4,78)
2. gọi lsof
từ Python
Bạn sẽ có thể gọi lsof
và đọc kết quả, từ Python, sử dụng các mô-đun subprocess
, như vậy:
from subprocess import Popen, PIPE
p1 = Popen(['lsof', '-a', '-p23819', '-i4'], stdout=PIPE)
p2 = Popen(["grep", "LISTEN"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
Hy vọng điều này sẽ hữu ích!
Bạn có thể sử dụng psutil:
>>> import psutil
>>> p = psutil.Process(2549)
>>> p.name()
'proftpd: (accepting connections)'
>>> p.connections()
[connection(fd=1, family=10, type=1, local_address=('::', 21), remote_address=(), status='LISTEN')]
... Để lọc cho ổ cắm nghe:
>>> [x for x in p.get_connections() if x.status == psutil.CONN_LISTEN]
[connection(fd=1, family=10, type=1, local_address=('::', 21), remote_address=(), status='LISTEN')]
>>>
Một điều mà không được đề cập. Hầu hết các ứng dụng cổng trong python đều lấy một đối số dòng lệnh. Bạn có thể phân tích cú pháp/proc/pid/cmdline và phân tích số cổng. Điều này tránh được chi phí lớn của việc sử dụng ss hoặc netstat trên các máy chủ với một tấn kết nối.
Cảm ơn. psutil là một mô-đun tốt. Nhưng vấn đề duy nhất là sử dụng mô-đun cần phải được cài đặt trước. Và cài đặt psutil cần gcc và các tiêu đề python được cài đặt. Vì vậy, dự án sử dụng psutil sẽ khó cài đặt. – mtoloo
psutil cần gcc vì nó chứa mã C cần được biên dịch. Tôi sẽ không đi xa như nói rằng đó là khó khăn để cài đặt, đặc biệt là trên Linux. Trên Ubuntu, ví dụ, bạn chỉ cần "apt-get install python-dev" và "pip install psutil" và bạn đã hoàn tất. –