Jak uzyskać tylko PID, bez żadnych dodatkowych informacji, procesu działającego na porcie 3000?

18

Używam CentOS 7. Chcę uzyskać PID (jeśli taki istnieje) procesu działającego na porcie 3000. Chciałbym uzyskać ten PID w celu zapisania go w zmiennej w skrypcie powłoki. Do tej pory mam

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

ale nie mogę wymyślić, jak samodzielnie wyodrębnić PID bez tych wszystkich dodatkowych informacji.

Dave
źródło
sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'. Potrzebujesz wyjaśnienia?
user996142
2
Nie jest wymagane żadne wyjaśnienie, ale powoduje to błąd „ss: invalid option -„ H ”.
Dave
Prawdopodobnie masz stary ssbez tej opcji. Powinien działać nawet bez niego:sudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
użytkownik996142
2
@ user996142 niezbyt pomocny komentarz. może być dobrą odpowiedzią
aaaaa mówi o przywróceniu Moniki

Odpowiedzi:

33

Inne możliwe rozwiązanie:

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

Na przykład:

# 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
Jurij Gonczaruk
źródło
Próbowałem „lsof -t -i: 3000 TCP: LISTEN” i dostałem błąd, „lsof: błąd statusu w TCP: LISTEN: Brak takiego pliku lub katalogu”
Dave
@Dave Uruchom bez TCP:LISTEN.
Xiong Chiamiov
2
@Dave Brakuje mi -sklucza. Naprawiłem to we wzór. Przykład miał ten klucz.
Yurij Goncharuk
Odpowiednie narzędzie do pracy.
Johannes Kuhn
10

Spróbuj tego:

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

(wymaga psmiscpakietu)

Należy pamiętać, że jest to niezawodne tylko wtedy, gdy jest uruchamiane przez użytkownika root. Inni użytkownicy mogą mieć tylko nadzieję, że znajdą procesy działające z tym samym użytkownikiem.


Nudne wytłumaczenie dostępu tylko do roota z przykładem tutaj.
Bez względu na zastosowaną metodę (fuser, ss, lsof, ...) wszystkie kończą dopasowywanie dostępnej listy deskryptorów procesu do dostępnej listy połączeń sieciowych (np. Dla tcp, w której jest dostępna /proc/net/tcp).
Na przykład próba uzyskania identyfikatora PID przy użyciu portu 22/tcp(z 22 = 0x0016) zakończy się takim rodzajem porównania:

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

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

Ponieważ ten deskryptor fd jest dostępny tylko dla jego użytkownika (który w tym przykładzie jest rootem) lub root, tylko ten użytkownik lub root może dowiedzieć się, że pid to 358.

AB
źródło
4

Chociaż lsofjest -tto najprostszy sposób, aby uzyskać PID, lsofma również sposoby, aby wybrać inne pola za pomocą -Fopcji:

$ 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

Z takim wyjściem (pamiętaj, że PID i deskryptory plików są zawsze drukowane):

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

Więc jeśli chcesz identyfikator grupy procesów zamiast PID, możesz:

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

Właśnie tego dokładnie potrzebujesz

sudo lsof -n -i :3000  | awk '/LISTEN/{print $2}'
12726
12730
12732
Arushix
źródło
1

Uwaga: Mogę to przetestować tylko na RedHat.

Czy powinno być możliwe netstat?

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

-n dla portów numerycznych
-l dla portów nasłuchiwania
-p aby zobaczyć PID

Możesz użyć przełączników --inet lub --inet6 , aby nakazać netstatwyszukiwanie tylko odpowiednio IPv4 lub IPv6, w przeciwnym razie możesz uzyskać dwa wyniki.

Alternatywnie możesz powiedzieć, awkaby wydrukować tylko raz

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

W awkpo prostu użyć „ / ” z netstat„s wyjście PID / programu jako separatora.

Robert Riedl
źródło