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.
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
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.
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
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.