추가 정보 없이 포트 3000에서 실행되는 프로세스의 PID만 어떻게 얻을 수 있나요?

추가 정보 없이 포트 3000에서 실행되는 프로세스의 PID만 어떻게 얻을 수 있나요?

CentOS 7을 사용하고 있습니다. 포트 3000에서 실행 중인 프로세스의 PID가 있으면 가져오고 싶습니다. 이 PID를 가져와서 쉘 스크립트의 변수에 저장하고 싶습니다. 지금까지 나는

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

하지만 이 추가 정보가 없으면 PID를 단독으로 분리하는 방법을 알 수 없습니다.

답변1

또 다른 가능한 해결책:

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

예를 들어:

# 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

답변2

이 시도:

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

( psmisc패키지가 필요함)

이는 루트 사용자가 실행할 때만 신뢰할 수 있습니다. 다른 사용자는 동일한 사용자로 실행 중인 프로세스만 찾기를 바랄 수 있습니다.


루트 전용 액세스에 대한 지루한 설명을 보려면 여기의 예를 참조하세요.
어떤 방법(fuser, ss, lsof...)을 사용하든 사용 가능한 프로세스 설명자 목록이 사용 가능한 네트워크 연결 목록과 일치하게 됩니다(예: tcp의 경우 에서 사용 가능 /proc/net/tcp).
예를 들어, 22/tcp포트(22 = 0x0016)를 사용하여 pid를 얻으려고 하면 다음 비교로 끝납니다.

다음의 항목 /proc/net/tcp:
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 141408 1 000000000a9ac1b5 100 0 0 10 0

그리고:
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]

이 fd 설명자는 해당 사용자(이 경우 루트임) 또는 루트만 사용할 수 있으므로 해당 사용자 또는 루트만 pid 358을 찾을 수 있습니다.

답변3

lsofs가 -tPID를 얻는 가장 간단한 방법이지만 다음 lsof옵션을 사용하여 다른 필드를 선택할 수도 있습니다 -F.

$ 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

출력은 다음과 같습니다(PID 및 파일 설명자는 항상 인쇄됩니다).

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

따라서 PID 대신 프로세스 그룹 ID를 원하면 다음과 같이 할 수 있습니다.

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

답변4

경고: RedHat에서만 테스트할 수 있습니다.

로 가능해야 합니까 netstat?

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

-N디지털 포트의 경우
-엘포트에서 수신하는 데 사용됨
-피PID 보기

당신은 그것을 사용할 수 있습니다--inet또는--inet6스위치는 netstat각각 IPv4 또는 IPv6만 찾도록 지시합니다. 그렇지 않으면 두 결과를 모두 얻을 수 있습니다.

awk아니면 한 번만 인쇄하도록 지시할 수도 있습니다 .

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

우리는 awk'만 사용합니다./' netstat프로그램의 PID/출력에서 구분 기호로 사용됩니다.

관련 정보