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.


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

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.


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

2

Właśnie tego dokładnie potrzebujesz

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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.