Come posso ottenere solo il PID, senza ulteriori informazioni, di un processo in esecuzione sulla porta 3000?


18

Sto usando CentOS 7. Voglio ottenere il PID (se esiste) del processo in esecuzione sulla porta 3000. Vorrei ottenere questo PID allo scopo di salvarlo in una variabile in uno script di shell. Finora l'ho fatto

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

ma non riesco a capire come isolare il PID da solo senza tutte queste informazioni extra.


sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'. Hai bisogno di spiegazioni?
user996142

2
Non è necessaria alcuna spiegazione, ma ciò si traduce in un errore "ss: invalid option - 'H'".
Dave,

Probabilmente hai un vecchio sssenza di questa opzione. Dovrebbe funzionare anche senza di essa:sudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
user996142

2
@ user996142 non è un commento molto utile. potrebbe essere una buona risposta però
aaaaa dice di reintegrare Monica

Risposte:


33

Un'altra possibile soluzione:

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

Per esempio:

# 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

Ho provato "lsof -t -i: 3000 TCP: LISTEN" e ho ottenuto l'errore "lsof: errore di stato su TCP: LISTEN: nessun file o directory"
Dave,

@Dave Eseguilo senza TCP:LISTEN.
Xiong Chiamiov

2
@Dave Mi manca la -schiave. L'ho risolto in modo regolare. Un esempio aveva questa chiave.
Yurij Goncharuk,

Strumento giusto per il lavoro.
Johannes Kuhn,

10

Prova questo:

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

(richiede psmiscpacchetto)

Si noti che ciò è affidabile solo se eseguito dall'utente root. Altri utenti possono solo sperare di trovare processi in esecuzione con lo stesso utente.


Spiegazione noiosa per l'accesso root solo con un esempio qui.
Qualunque sia il metodo utilizzato (fuser, ss, lsof, ...) finiscono tutti per abbinare l'elenco disponibile dei descrittori di processo a un elenco disponibile di connessioni di rete (ad es. Per tcp è disponibile in /proc/net/tcp).
Ad esempio, provare a ottenere il pid usando port 22/tcp(con 22 = 0x0016) finirebbe per fare questo tipo di confronto:

Ingresso da /proc/net/tcp:
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0

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

Poiché questo descrittore fd è disponibile solo per l'utente (che in questo esempio è root) o root, solo quell'utente o root può scoprire che il pid è 358.


4

Mentre lsof's -tè il modo più semplice per ottenere il PID, lsofha anche modi per selezionare altri campi utilizzando l' -Fopzione di:

$ 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

Con un output simile (notare che i descrittori di file e PID sono sempre stampati):

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

Pertanto, se si desidera l'ID del gruppo di processi anziché il PID, è possibile:

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

2

Questo è esattamente ciò di cui hai bisogno

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

1

Avvertenza: posso testarlo solo su RedHat.

Dovrebbe essere possibile con netstat?

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

-n per le porte numeriche
-l per le porte di ascolto
-p per vedere i PID

Puoi usare gli switch --inet o --inet6 per dire netstatdi cercare rispettivamente solo IPv4 o IPv6, altrimenti potresti ottenere due risultati.

In alternativa puoi dire awkdi stampare una sola volta

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

In awkusiamo semplicemente l' output ' / ' from netstatdel programma PID / come separatore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.