Làm cách nào để tôi chỉ nhận được PID, mà không có bất kỳ thông tin bổ sung nào về quy trình đang chạy trên cổng 3000?


18

Tôi đang sử dụng CentOS 7. Tôi muốn nhận được PID (nếu có tồn tại) của quy trình đang chạy trên cổng 3000. Tôi muốn có được PID này cho mục đích lưu nó vào một biến trong tập lệnh shell. Cho đến nay tôi có

[rails@server proddir]$ sudo ss -lptn 'sport = :3000'
State      Recv-Q Send-Q                           Local Address:Port                                          Peer Address:Port
Cannot open netlink socket: Protocol not supported
LISTEN     0      0                                            *:3000                                                     *:*                   users:(("ruby",pid=4861,fd=7),("ruby",pid=4857,fd=7),("ruby",pid=4855,fd=7),("ruby",pid=4851,fd=7),("ruby",pid=4843,fd=7))

nhưng tôi không thể tự mình tìm ra cách cô lập PID mà không có tất cả thông tin bổ sung này.


sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'. Bạn có cần giải thích?
user996142

2
Không cần giải thích nhưng điều này dẫn đến một tùy chọn "ss: không hợp lệ - 'H'".
Dave

Bạn có thể có một cái cũ ssmà không có tùy chọn này. Nên hoạt động ngay cả khi không có nó:sudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
user996142

2
@ user996142 không phải là một bình luận rất hữu ích. có thể là một câu trả lời tốt mặc dù
aaaaa nói phục hồi lại

Câu trả lời:


33

Một giải pháp khả thi khác:

lsof -t -i :<port> -s <PROTO>:LISTEN

Ví dụ:

# lsof -i :22 -s TCP:LISTEN
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1392 root    3u  IPv4  19944      0t0  TCP *:ssh (LISTEN)
sshd    1392 root    4u  IPv6  19946      0t0  TCP *:ssh (LISTEN)
# lsof -t -i :22 -s TCP:LISTEN
1392

Đã thử "lsof -t -i: 3000 TCP: LISTEN" và đã gặp lỗi, "lsof: lỗi trạng thái trên TCP: LISTEN: Không có tệp hoặc thư mục như vậy"
Dave

@Dave Chạy nó mà không có TCP:LISTEN.
Xiong Chiamiov

2
@ Tôi đã bỏ lỡ -schìa khóa. Tôi đã sửa nó theo mô hình. Một ví dụ có chìa khóa này.
Yurij Goncharuk

Công cụ phù hợp cho công việc.
Julian Kuhn

10

Thử đi:

pid=$(fuser 3000/tcp 2>/dev/null)

(yêu cầu psmiscgói)

Xin lưu ý rằng điều này chỉ đáng tin cậy khi được chạy bởi người dùng root. Những người dùng khác chỉ có thể hy vọng tìm thấy các quy trình chạy với cùng một người dùng.


Giải thích nhàm chán cho quyền truy cập chỉ root với một ví dụ ở đây.
Dù sử dụng phương pháp nào (fuser, ss, lsof, ...) thì tất cả chúng đều phù hợp với danh sách mô tả quy trình có sẵn với một danh sách kết nối mạng có sẵn (ví dụ: tcp có sẵn trong đó /proc/net/tcp).
Ví dụ: cố gắng lấy pid bằng cổng 22/tcp(với 22 = 0x0016) sẽ kết thúc bằng cách so sánh này:

Nhập từ /proc/net/tcp:
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0

với:
dr-x------. 2 root root 0 May 14 17:59 /proc/358/fd lrwx------. 1 root root 64 May 14 17:59 /proc/358/fd/3 -> socket:[141408]

Vì mô tả fd này chỉ có sẵn cho người dùng của nó (mà tình cờ là root trong ví dụ này) hoặc root, chỉ người dùng hoặc root đó mới có thể tìm ra pid là 358.


4

Trong khi lsof's -tlà cách đơn giản nhất để có được những PID, lsofcũng có nhiều cách để lựa chọn các lĩnh vực khác bằng cách sử dụng -Ftùy chọn:

$ lsof -F'?'
lsof:   ID    field description
     a    access: r = read; w = write; u = read/write
     c    command name
     d    device character code
     D    major/minor device number as 0x<hex>
     f    file descriptor (always selected)
     G    file flaGs
     i    inode number
     k    link count
     K    task ID (TID)
     l    lock: r/R = read; w/W = write; u = read/write
     L    login name
     m    marker between repeated output
     n    comment, name, Internet addresses
     o    file offset as 0t<dec> or 0x<hex>
     p    process ID (PID)
     g    process group ID (PGID)
     P    protocol name
     r    raw device number as 0x<hex>
     R    paRent PID
     s    file size
     S    stream module and device names
     t    file type
     T    TCP/TPI info
     u    user ID (UID)
     0    (zero) use NUL field terminator instead of NL

Với đầu ra như vậy (lưu ý rằng bộ mô tả PID và tệp luôn được in):

$ sudo lsof -F cg -i :22 -s TCP:LISTEN 
p901
g901
csshd
f3
f4

Vì vậy, nếu bạn muốn ID nhóm quy trình thay vì PID, bạn có thể làm:

$ sudo lsof -F g -i :22 -s TCP:LISTEN | awk '/^g/{print substr($0, 2)}'
901

2

Đây là những gì bạn cần chính xác

sudo lsof -n -i :3000  | awk '/LISTEN/{print $2}'
12726
12730
12732

1

Hãy cẩn thận: Tôi chỉ có thể kiểm tra điều này trên RedHat.

Có nên với netstat?

 sudo netstat -npl --inet | awk '/:3000/' | awk -F "[ /]+" '{print $7}'

-n cho các cổng số
-l cho các cổng nghe
-p để xem các PID

Bạn có thể sử dụng --inet hoặc --inet6 chuyển sang nói netstatđể chỉ nhìn cho IPv4 hay IPv6 tương ứng, nếu không bạn có thể nhận được hai kết quả.

Ngoài ra, bạn có thể yêu awkcầu chỉ in một lần

sudo netstat -npl | awk '/:3000/' | awk -F "[ /]+" '{print $7; exit}' 

Trong awkchúng ta chỉ cần sử dụng đầu ra ' / ' từ netstatđầu ra của chương trình PID / như một dấu phân cách.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.