3000 numaralı bağlantı noktasında çalışan bir işlemin ek bilgileri olmadan yalnızca PID'sini nasıl edinebilirim?


18

CentOS 7 kullanıyorum. 3000 numaralı bağlantı noktasında çalışan işlemin PID'sini (varsa) almak istiyorum. Kabuk betiğindeki bir değişkene kaydetmek amacıyla bu PID'yi almak istiyorum. Şimdiye kadar var

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

ancak tüm bu ekstra bilgiler olmadan PID'nin nasıl yalıtılacağını anlayamıyorum.


sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'. Açıklamaya mı ihtiyacınız var?
user996142

2
Açıklama gerekmez, ancak bu bir "ss: geçersiz seçenek - 'H'" hatasıyla sonuçlanır.
Dave

Muhtemelen ssbu seçenek olmadan bir yaşınız var . Onsuz da çalışmalı:sudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
user996142

2
@ user996142 çok yararlı bir yorum değil. yine de iyi bir cevap olabilir
aaaaa Monica'nın

Yanıtlar:


33

Başka bir olası çözüm:

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

Örneğin:

# 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: LISTEN" komutunu denedim ve "lsof: TCP'de durum hatası: LISTEN: Böyle bir dosya veya dizin yok" hatası aldı
Dave,

@Dave Olmadan çalıştırın TCP:LISTEN.
Xiong Chiamiov

2
@ -sAnahtarı kaçırdım . Desende düzelttim. Bir örnekte bu anahtar vardı.
Yurij Goncharuk

İş için doğru araç.
Johannes Kuhn

10

Bunu dene:

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

( psmiscpaket gerektirir )

Bunun yalnızca kullanıcı kökü tarafından çalıştırıldığında güvenilir olduğunu lütfen unutmayın. Diğer kullanıcılar yalnızca aynı kullanıcıyla çalışan işlemleri bulmayı umabilir.


Burada sadece bir örnekle root erişimi için sıkıcı açıklama.
Hangi yöntem kullanılırsa kullanılsın (fuser, ss, lsof, ...) bunların hepsi kullanılabilir işlem tanımlayıcıları listesini kullanılabilir bir ağ bağlantıları listesiyle eşleştirir (örneğin, içinde tcp için /proc/net/tcp).
Örneğin, bağlantı noktasını 22/tcp(22 = 0x0016 ile) kullanarak pid'i almaya çalışmak, bu tür bir karşılaştırma yapar:

Giriş yeri /proc/net/tcp:
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0

ile:
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]

Bu fd tanımlayıcısı yalnızca kullanıcısı (bu örnekte kök olan) veya kök için kullanılabilir olduğundan, yalnızca bu kullanıcı veya kök pid'in 358 olduğunu bulabilir.


4

İken lsof'ın -tPıD'YI almak için en basit yoldur, lsofayrıca kullanan diğer alanları seçmek için yollar vardır -Fseçeneği:

$ 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

Bu şekilde çıktı ile (PID ve dosya tanımlayıcılarının her zaman yazdırıldığını unutmayın):

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

Dolayısıyla, PID yerine işlem grubu kimliğini istiyorsanız, şunları yapabilirsiniz:

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

2

Tam olarak ihtiyacınız olan şey bu

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

1

Dikkat: Bunu sadece RedHat'ta test edebilirim.

Mümkün netstatmü?

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

-n sayısal bağlantı noktaları için
-l dinleme bağlantı noktaları için
-p -PID'leri görmek için

Sen kullanabilirsiniz --inet veya --inet6 anlatmak için anahtarları netstataksi takdirde iki sonuç almak olabilir, IPv4 veya sırasıyla IPv6 için sadece görünüm.

Alternatif olarak awkyalnızca bir kez yazdırmayı söyleyebilirsiniz

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

Gelen awkbiz sadece 'kullanmak / dan' netstatayırıcı olarak PID / program 'nin çıkışı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.