4

/proc/net/tcp 为我提供了套接字的本地地址、端口和 inode 编号(例如,0.0.0.0:5432 和 9289)。

鉴于上述信息,我想找到特定进程的 PID。

可以打开 /proc 中的每个编号文件夹,然后使用诸如“$ sudo ls -l /proc/*/fd/ 2>/dev/null | grep socket”之类的 shell 命令检查符号链接是否匹配套接字/inode 编号。然而,这似乎比必要的计算成本更高,因为在任何给定系统上,<5% 的进程具有打开的 TCP 套接字。

找到打开给定套接字的 PID 的最有效方法是什么?我更喜欢使用标准库,我目前正在使用 Python 3.2.3 进行开发。

编辑:从问题中删除了代码示例,因为它们现在包含在下面的答案中。

4

2 回答 2

5

下面的代码实现了最初的目标:

def find_pid(inode):

    # get a list of all files and directories in /proc
    procFiles = os.listdir("/proc/")

    # remove the pid of the current python process
    procFiles.remove(str(os.getpid()))

    # set up a list object to store valid pids
    pids = []

    for f in procFiles:
        try:
            # convert the filename to an integer and back, saving the result to a list
            integer = int(f)
            pids.append(str(integer))
        except ValueError:
            # if the filename doesn't convert to an integer, it's not a pid, and we don't care about it
            pass

    for pid in pids:
        # check the fd directory for socket information
        fds = os.listdir("/proc/%s/fd/" % pid)
        for fd in fds:
            # save the pid for sockets matching our inode
            if ('socket:[%d]' % inode) == os.readlink("/proc/%s/fd/%s" % (pid, fd)):
                return pid
于 2013-02-03T19:52:39.620 回答
2

我不知道如何在 python 中执行此操作,但您可以使用lsof(1)

lsof -i | awk -v sock=158384387 '$6 == sock{print $2}'

158384387是套接字的 inode。然后使用subprocess.Popen.

如果您想查看其他用户打开的套接字,则必须使用 sudo(8)。

于 2013-02-02T23:29:28.670 回答