web-dev-qa-db-fra.com

Comment obtenir uniquement le PID, sans aucune information supplémentaire, d'un processus en cours d'exécution sur Port 3000?

J'utilise Centos 7. Je veux obtenir le PID (le cas échéant) du processus en cours d'exécution sur le port 3000. J'aimerais obtenir ce PID à des fins de la sauver à une variable dans un script shell. Jusqu'à présent j'ai

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

mais je ne peux pas comprendre comment isoler le PID tout en soi sans toutes ces informations supplémentaires.

18
Dave

Une autre solution possible:

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

Par exemple:

# 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
33
Yurij Goncharuk

Essaye ça:

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

(Nécessite psmisc paquet)

Veuillez noter que cela est fiable que lorsqu'il est exécuté par la racine de l'utilisateur. Les autres utilisateurs ne peuvent espérer que les processus fonctionnant avec le même utilisateur.


Explication ennuyeuse pour racine uniquement accès avec un exemple ici.
[.____] Quelle que soit la méthode utilisée (Fuser, SS, LSOF, ...), ils finissent tous à correspondre à la liste descripteurs de processus disponible dans une liste disponible des connexions réseau (par exemple, pour TCP qu'il est disponible dans /proc/net/tcp).
[.____] Par exemple, essayez d'obtenir le PID à l'aide du port 22/tcp (Avec 22 = 0x0016) finirait par faire ce genre de comparaison:

Entrée de /proc/net/tcp:
[.____] 0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0

avec:
[.____] 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]

Comme ce descripteur FD n'est disponible que pour son utilisateur (qui se produise en racine dans cet exemple) ou racine, seul cet utilisateur ou racine peut découvrir le PID est de 358.

10
A.B

Tandis que lsof 's -t est le moyen le plus simple d'obtenir le PID, lsof a également des moyens de sélectionner d'autres champs à l'aide de -F Option:

$ 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

Avec la sortie comme (note que les descripteurs PID et de fichiers sont toujours imprimés):

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

Donc, si vous vouliez que l'ID de groupe de processus au lieu du PID, vous pourriez faire:

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

CAVEAT: Je ne peux que tester cela sur Redhat.

Devrait être possible avec netstat?

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

- N pour les ports numériques
[.____] - l pour les ports d'écoute
[.____] - P pour voir PIDS

Vous pouvez utiliser -- inet ou -- INET6 Commutateurs à raconter netstat Pour rechercher uniquement IPv4 ou IPv6, sinon vous pourriez obtenir deux résultats.

Sinon, vous pouvez dire awk d'imprimer une seule fois

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

Dans awk nous n'utilisons que le '/' de netstat 's la sortie du PID/programme en tant que séparateur.

1
Robert Riedl