ฉันจะรับเฉพาะ PID ที่ไม่มีข้อมูลเพิ่มเติมใด ๆ ของกระบวนการที่ทำงานบนพอร์ต 3000 ได้อย่างไร


18

ฉันใช้ CentOS 7 ฉันต้องการรับ PID (ถ้ามี) ของกระบวนการที่ทำงานบนพอร์ต 3000 ฉันต้องการรับ PID นี้เพื่อวัตถุประสงค์ในการบันทึกเป็นตัวแปรในเชลล์สคริปต์ จนถึงตอนนี้ฉันมี

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

แต่ฉันไม่สามารถหาวิธีที่จะแยก PID ทั้งหมดได้ด้วยตัวเองโดยไม่มีข้อมูลเพิ่มเติมทั้งหมดนี้


sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'. คุณต้องการคำอธิบายหรือไม่?
user996142

2
ไม่ต้องการคำอธิบาย แต่จะส่งผลให้เกิดข้อผิดพลาด "ss: ตัวเลือกที่ไม่ถูกต้อง - 'H'"
เดฟ

คุณอาจมีรุ่นเก่าที่ssไม่มีตัวเลือกนี้ ควรใช้งานได้โดยไม่ต้องใช้:sudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
user996142

2
@ user996142 ไม่ใช่ความคิดเห็นที่เป็นประโยชน์มาก อาจเป็นคำตอบที่ดี
aaaaa พูดว่าคืนสถานะโมนิก้า

คำตอบ:


33

ทางออกที่เป็นไปได้อื่น:

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

ตัวอย่างเช่น:

# 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

พยายาม "lsof -t -i: 3000 TCP: ฟัง" และได้รับข้อผิดพลาด "lsof: ข้อผิดพลาดเกี่ยวกับสถานะ TCP: ฟัง: ไม่มีแฟ้มหรือไดเรกทอรีดังกล่าว"
เดฟ

@Dave TCP:LISTENเรียกได้โดยไม่ต้อง
Xiong Chiamiov

2
@ เดฟฉันได้พลาด-sกุญแจ ฉันแก้ไขมันในรูปแบบ ตัวอย่างมีกุญแจนี้
Yurij Goncharuk

เครื่องมือที่เหมาะสมสำหรับงาน
Johannes Kuhn

10

ลองสิ่งนี้:

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

(ต้องมีpsmiscแพ็คเกจ)

โปรดทราบว่านี่มีความน่าเชื่อถือเฉพาะเมื่อรันโดยผู้ใช้รูท ผู้ใช้คนอื่นสามารถหวังได้ว่าจะพบกระบวนการที่ทำงานกับผู้ใช้คนเดียวกัน


คำอธิบายที่น่าเบื่อสำหรับการเข้าถึงรูทด้วยตัวอย่างที่นี่
ไม่ว่าวิธีการใดที่ใช้ (fuser, ss, lsof, ... ) พวกเขาทั้งหมดจะจับคู่รายการ descriptors ของกระบวนการที่มีอยู่กับรายการการเชื่อมต่อเครือข่ายที่มีอยู่ (เช่นสำหรับ tcp ที่มีอยู่/proc/net/tcp)
ตัวอย่างเช่นการพยายามรับ pid โดยใช้พอร์ต22/tcp(ด้วย 22 = 0x0016) จะเป็นการเปรียบเทียบชนิดนี้:

รายการจาก/proc/net/tcp:
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0

ด้วย:
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]

เนื่องจาก fd descriptor นี้พร้อมใช้งานสำหรับผู้ใช้เท่านั้น (หรือเป็นรูทในตัวอย่างนี้) หรือรูทเฉพาะผู้ใช้หรือรูทเท่านั้นที่สามารถค้นหา pid ได้คือ 358


4

ในขณะที่lsof's -tเป็นวิธีที่ง่ายที่จะได้รับ PID, lsofนอกจากนี้ยังมีวิธีในการเลือกสาขาอื่น ๆ โดยใช้-Fตัวเลือก:

$ 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

ด้วยเอาต์พุตเช่นนั้น (โปรดทราบว่า PID และตัวอธิบายไฟล์จะถูกพิมพ์เสมอ):

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

ดังนั้นหากคุณต้องการ ID กลุ่มกระบวนการแทนที่จะเป็น PID คุณสามารถทำได้:

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

2

นี่คือสิ่งที่คุณต้องการอย่างแน่นอน

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

1

Caveat: ฉันสามารถทดสอบได้ที่ RedHat เท่านั้น

ควรจะเป็นไปได้ด้วยnetstat?

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

-nสำหรับพอร์ตที่เป็นตัวเลข
-lสำหรับการฟังพอร์ต
-pเพื่อดู PID

คุณสามารถใช้--inetหรือ--inet6สวิตช์เพื่อบอกnetstatให้ค้นหาเฉพาะ IPv4 หรือ IPv6 ตามลำดับมิฉะนั้นคุณอาจได้รับผลลัพธ์สองรายการ

หรือคุณสามารถบอกawkให้พิมพ์เพียงครั้งเดียว

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

ในawkเราเพียงแค่ใช้ ' / ' จากnetstatเอาต์พุตของ PID / โปรแกรมเป็นตัวคั่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.