从Python中查找Linux中特定PID的命令

时间:2009-09-17 19:44:10

标签: python linux process

我想知道是否可以找到PID设置的“命令”。当我说命令时,我的意思是你在linux shell中运行命令“top”时在最后一列中看到的内容。当我有一个特定的PID时,我想以某种方式从Python获取这些信息。

任何帮助都会很棒。感谢。

7 个答案:

答案 0 :(得分:11)

请不要在生产代码中使用/proc文件系统。相反,使用明确定义的POSIX接口,例如glibc调用和标准shell命令!让Linux世界更加标准化,它确实需要!

通过调用shell命令

可以很好地实现所需
ps -p <YOUR PID> -o cmd h

不需要解析!

更不用说从python读取shell命令输出比从/proc中的文件读取更费力。这使得您的程序更加便携!

答案 1 :(得分:8)

查看/proc/$PID/cmdline

答案 2 :(得分:6)

阅读ps命令并解析其输出。

ps -p [PID] -o cmd 

应该这样做

答案 3 :(得分:5)

查看/proc/$PID/cmdline,然后查看/proc/$PID/exe上的os.readlink()。

/proc/$PID/cmdline不一定是正确的,因为程序可以更改其参数向量,或者它可能不包含完整路径。我目前的流程列表中的三个例子是:

  • avahi-daemon: chroot helper
  • qmgr -l -t fifo -u
  • /usr/sbin/postgrey --pidfile=/var/run/postgrey.pid --daemonize --inet=127.0.0.1:60000 --delay=55

第一个显而易见的是 - 它不是有效的路径或程序名称。第二个只是一个没有路径名的可执行文件。第三个看起来没问题,但整个命令行实际上在argv[0]中,空格分隔了参数。通常你应该有NUL分开的参数。

这一切都表明/proc/$PID/cmdline(或ps(1)输出)不可靠。

然而,/proc/$PID/exe也不是。(deleted)。通常它是可执行文件的符号链接,它是进程的主要文本段。但有时候,如果可执行文件不再存在于文件系统中,它就会有“/proc/$PID/exe”。

此外,作为文本段的程序并不总是您想要的。例如,上面/usr/sbin/postgrey示例中的/usr/bin/perl/proc/$PID/cmdline。所有解释过的脚本都是这种情况(#!)。

我决定解析/proc/$PID/exe - 获取向量的第一个元素,然后在其中查找空格,并在第一个空格之前获取所有空格。如果那是一个可执行文件 - 我就停在那里。否则,我在(deleted)上执行了readlink(2)并删除了最后的所有“/proc/$PID/cmdline”字符串。如果可执行文件名实际上包含空格,则第一部分将失败。你无能为力。

顺便说一句。使用ps(1)而不是/proc/$PID/exe的参数在这种情况下不适用,因为您将回退到/proc。您将依赖于/proc/$PID/cmdline文件系统,因此您也可以使用read(2)而不是pipe(2),fork(2),execve(2),readdir(3)...来阅读它。写(2),读(2)。虽然ps和{{1}}从python代码行的角度来看可能是相同的,但ps后面的场景还有很多。

答案 4 :(得分:4)

一个有趣的Python包是psutil

例如,要获取特定PID的命令:

import psutil
pid = 1234 # The pid whose info you're looking for
p = psutil.Process(pid)
print p.cmdline

最后一行会打印['/usr/bin/python', 'main.py']

之类的内容

获取此信息的更强大的方法,如果pid表示某个进程不再运行,请小心:

import psutil
pid = 1234 # The pid whose info you're looking for
if pid in psutil.get_pid_list():
    p = psutil.Process(pid)
    print p.cmdline

答案 5 :(得分:0)

proc文件系统导出此(和其他)信息。 查看/ proc / PID / cmd符号链接。

答案 6 :(得分:0)

这对我有用:

def filter_non_printable(str):
    ret=""
    for c in str:
        if ord(c) > 31 or ord(c) == 9:
            ret += c
        else:
            ret += " "
    return ret


#
# Get /proc/<cpu>/cmdline information
#
def pid_name(pid):
    try:
        with open(os.path.join('/proc/', pid, 'cmdline'), 'r') as pidfile:
            return filter_non_printable(pidfile.readline())

    except Exception:
        pass
        return