Wie erhalte ich nur die PID ohne zusätzliche Informationen eines Prozesses, der auf Port 3000 ausgeführt wird?

18

Ich verwende CentOS 7. Ich möchte die PID (falls vorhanden) des auf Port 3000 ausgeführten Prozesses abrufen. Ich möchte diese PID abrufen, um sie in einer Variablen in einem Shell-Skript zu speichern. Soweit habe ich

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

aber ich kann nicht herausfinden, wie man die PID ohne all diese zusätzlichen Informationen isoliert.

Dave
quelle
sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'. Benötigen Sie eine Erklärung?
user996142
2
Es ist keine Erklärung erforderlich, dies führt jedoch zu einem "ss: invalid option - 'H'" - Fehler.
Dave
Sie haben wahrscheinlich einen alten ssohne diese Option. Sollte auch ohne funktionieren:sudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
user996142
2
@ user996142 kein sehr hilfreicher Kommentar.
Könnte

Antworten:

33

Eine andere mögliche Lösung:

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

Beispielsweise:

# 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
Yurij Goncharuk
quelle
Versuchte "lsof -t -i: 3000 TCP: LISTEN" und bekam den Fehler "lsof: Statusfehler auf TCP: LISTEN: Keine solche Datei oder Verzeichnis"
Dave
@ Dave Run it without TCP:LISTEN.
Xiong Chiamiov
2
@ Dave Ich habe -sSchlüssel vermisst . Ich habe es in Muster behoben. Ein Beispiel hatte diesen Schlüssel.
Yurij Goncharuk
Richtiges Werkzeug für den Job.
Johannes Kuhn
10

Versuche dies:

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

(benötigt psmiscPaket)

Bitte beachten Sie, dass dies nur dann zuverlässig ist, wenn es vom Benutzer root ausgeführt wird. Andere Benutzer können nur hoffen, Prozesse zu finden, die mit demselben Benutzer ausgeführt werden.


Langweilige Erklärung für root nur mit einem Beispiel hier.
Unabhängig von der verwendeten Methode (fuser, ss, lsof, ...) stimmen alle die verfügbaren Prozessdeskriptoren mit den verfügbaren Netzwerkverbindungen überein (z. B. für tcp ist dies in verfügbar /proc/net/tcp).
Wenn Sie beispielsweise versuchen, die PID über den Port 22/tcp(mit 22 = 0x0016) abzurufen, wird der folgende Vergleich durchgeführt:

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

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

Da dieser fd-Deskriptor nur für seinen Benutzer (der in diesem Beispiel root ist) oder root verfügbar ist, kann nur dieser Benutzer oder root feststellen, dass die pid 358 lautet.

AB
quelle
4

Während lsof‚s -tder einfachste Weg ist , um die PID zu bekommen, lsofhat auch auf andere Weise Felder mit der Auswahl -FOption:

$ 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

Bei Ausgabe wie folgt (beachten Sie, dass PID- und Dateideskriptoren immer gedruckt werden):

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

Wenn Sie also die Prozessgruppen-ID anstelle der PID benötigen, können Sie Folgendes tun:

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

Genau das brauchen Sie

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

Einschränkung: Ich kann das nur mit RedHat testen.

Sollte mit möglich sein netstat?

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

-n für numerische Ports
-l zum Abhören von Ports
-p zum Anzeigen von PIDs

Sie können die Optionen --inet oder --inet6 verwenden , um anzugeben , dass netstatnur nach IPv4 oder IPv6 gesucht werden soll. Andernfalls erhalten Sie möglicherweise zwei Ergebnisse.

Alternativ können Sie festlegen awk, dass nur einmal gedruckt werden soll

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

In verwenden awkwir einfach das ' / ' von netstat's Ausgabe von PID / program als Trennzeichen.

Robert Riedl
quelle