ポート3000で実行されているプロセスの追加情報なしでPIDのみを取得するにはどうすればよいですか?


18

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を単独で分離する方法はわかりません。


sudo ss -lptnH "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'。説明が必要ですか?
user996142

2
説明は必要ありませんが、これにより「ss:invalid option-'H'」エラーが発生します。
デイブ

おそらくssこのオプションのない古いものがあります。それなしでも機能するはずですsudo ss -lptn "sport = :22" | awk -F " " '{printf $6}' | sed 's/.\+pid=\([0-9]\+\).\+/\1/g'
。– user996142

2
@ user996142はあまり有用なコメントではありません。けれども良い答えかもしれない
AAAAAはモニカ回復言う

回答:


33

別の可能な解決策:

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

試してみました"lsofを-t -i:3000 TCP:LISTEN"と、エラーを得ない"lsofを:TCP上のステータスエラーが:LISTEN:そのようなファイルやディレクトリを"
デイブ・

@Daveなしで実行しますTCP:LISTEN
Xiong Chiamiov

2
@デイブキーを逃しました-s。パターンで修正しました。例にはこのキーがありました。
ユーリゴンチャルク

仕事に最適なツール。
ヨハネ

10

これを試して:

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

psmiscパッケージが必要です)

これは、ユーザーrootによって実行された場合にのみ信頼できることに注意してください。他のユーザーは、同じユーザーで実行されているプロセスを見つけることのみを望みます。


ルート限定アクセスの退屈な説明とここの例。
使用する方法(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記述子はそのユーザー(この例ではたまたまroot)またはrootのみが使用できるため、そのユーザーまたはrootのみがpidが358であることがわかります。


4

ながらlsofさんは-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

2

これはまさにあなたが必要とするものです

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

1

警告:これはRedHatでのみテストできます。

で可能になりnetstatますか?

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

-nは数値ポート、
-lはリッスンポート、
-pはPIDを表示します。

--inetまたは--inet6スイッチを使用してnetstat、それぞれIPv4またはIPv6のみを探すように指示できます。そうしないと、2つの結果が得られる可能性があります。

または、awk一度だけ印刷するように指示できます

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

ではawk私たちは「を使用/から」をnetstatセパレータとしてPID /プログラムのの出力。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.