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を単独で分離する方法を理解できません。
別の可能な解決策:
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
これを試して:
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であることを確認できます。
lsof
の-t
はPIDを取得する最も簡単な方法ですが、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
これはあなたが正確に必要なものです
Sudo lsof -n -i :3000 | awk '/LISTEN/{print $2}'
12726
12730
12732
警告:これはRedHatでのみテストできます
netstat
で可能でしょうか?
Sudo netstat -npl --inet | awk '/:3000/' | awk -F "[ /]+" '{print $7}'
-n数値ポートの場合
-lリスニングポート用
-p PIDを表示する
-inetまたは-inet6スイッチを使用して、netstat
は、それぞれIPv4またはIPv6のみを検索します。それ以外の場合、2つの結果が得られることがあります。
または、awk
に1回だけ印刷するように指示することもできます
Sudo netstat -npl | awk '/:3000/' | awk -F "[ /]+" '{print $7; exit}'
awk
では、PID /プログラムのnetstat
の出力からの '/'をセパレーターとして使用します。