我正在使用下面的命令并尝试分隔列,我只想获取 PID 以在我的 python 脚本中使用它。
我可以轻松地逐行获取此内容,但是如何以非黑客方式分成列?
我可以轻松地按空间分割,但面对现实,这是一个糟糕的主意,有什么建议吗?
root@python-VirtualBox:/var/python# lsof | grep TCP
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 3449 root 3u IPv4 24248 0t0 TCP *:22 (LISTEN)
sshd 3449 root 4u IPv6 24257 0t0 TCP *:22 (LISTEN)
答案1
该lsof
命令功能非常齐全,允许您指定许多不同的搜索条件。特别是,该-i
选项允许您通过互联网地址(包括协议)进行搜索,从而grep
无需进行搜索。所以你可以替换
lsof | grep TCP
和
lsof -i TCP
lsof
还允许您使用该选项指定您感兴趣的字段-F
并仅输出这些字段(每行一个)。所以我们可以做
lsof -i TCP -F 'p'
输出使用 TCP 的进程的 PID 列表。
然而,每个 PID 都以“p”为前缀(例如“p156”),因此最终我们可以用来cut
获取数字 ID。这给了我们最终的命令
lsof -i TCP -F 'p' | cut -c 2-
当然@RobertL 的答案也非常好,但我喜欢挑战自己不使用 AWK 来解决我所有的文本处理挑战。
答案2
我认为awk
这有好处,因为它为您分割字段:
lsof | awk '$8 == "TCP" { print $2 }'
如果字段 8 是“TCP”,则打印字段 2。
答案3
在:
lsof -iTCP -Fp
出去:
p1135
p6326
p16841
p18130
p37908
p41768
p51944
p71882
p74759
p79636
p82203
答案4
唯一真正安全的选择是使用eg lsof -F0pn
,然后使用其他编程语言解析输出。在这种情况下,lsof 将发出由空字节分隔的字段,并且每个字段都以指定字段类型的字符开头。例如,p123<NULL>n/var/log/syslog<NULL>
这意味着 PID 123 打开的文件名为/var/log/syslog
.请注意,如果进程打开了多个文件,则p
(PID) 字段将仅列出一次,并且n
将出现描述文件的多个 (名称) 字段。
另请注意,即使您请求字段p
并n
带有-F
标志,lsof
也可能会发出其他字段,因此请准备好忽略您不感兴趣的字段。
这lsof
是 POSIX 规范的一部分,由于历史原因它有这种奇怪的行为:https://www.unix.com/man-page/posix/8/lsof/