【发布时间】:2009-09-17 19:44:09
【问题描述】:
我想知道是否有可能找出 PID 设置的“命令”。当我说命令时,我的意思是当您在 linux shell 中运行命令“top”时在最后一列中看到的内容。当我有一个特定的 PID 时,我想以某种方式从 Python 获取这些信息。
任何帮助都会很棒。谢谢。
【问题讨论】:
我想知道是否有可能找出 PID 设置的“命令”。当我说命令时,我的意思是当您在 linux shell 中运行命令“top”时在最后一列中看到的内容。当我有一个特定的 PID 时,我想以某种方式从 Python 获取这些信息。
任何帮助都会很棒。谢谢。
【问题讨论】:
使用 /proc 文件的缺点是可移植性较低,这可能是问题,也可能不是问题。以下是您可以使用标准 shell 命令的方法
ps -w -w -p <YOUR PID> -o cmd h
注意两个 -w 选项,它们指示 ps 不截断输出(默认情况下会截断)
从 python 读取其输出就像调用单个函数 subprocess.check_output() 记录的 here 一样简单。
【讨论】:
ps 从哪里获取命令行信息?”
/proc 中的文件)。但是当他们发明/foobar 系统而不是/proc 时,你将不得不重写你的程序。无论如何,也许我在 LSB 工作组工作时受到了脑损伤,但你真的应该坚持对你来说足够的标准——这是正在考虑的情况。
/proc/$PID/cmdline做)
/proc/$PID/cmdline
【讨论】:
一个有趣的 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())
【讨论】:
【讨论】:
查看/proc/$PID/cmdline,然后查看/proc/$PID/exe 上的os.readlink()。
/proc/$PID/cmdline 不一定是正确的,因为程序可以更改其参数向量,或者它可能不包含完整路径。我当前的进程列表中的三个示例是:
avahi-daemon: chroot helperqmgr -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)”。
此外,作为文本段的程序并不总是您想要的。例如,上面的/usr/sbin/postgrey 示例中的/proc/$PID/exe 是/usr/bin/perl。这将适用于所有解释脚本 (#!)。
我决定解析/proc/$PID/cmdline - 获取向量的第一个元素,然后在其中寻找空格,并在第一个空格之前获取所有元素。如果那是一个可执行文件 - 我停在那里。否则我在/proc/$PID/exe 上做了一个readlink(2) 并在最后删除了任何“(deleted)”字符串。如果可执行文件名中实际上包含空格,则第一部分将失败。您对此无能为力。
顺便说一句。使用 ps(1) 而不是 /proc/$PID/cmdline 的参数在这种情况下不适用,因为您将退回到 /proc/$PID/exe。您将依赖于/proc 文件系统,因此您最好使用 read(2) 而不是 pipe(2)、fork(2)、execve(2)、readdir(3)...、write( 2),阅读(2)。虽然从 Python 代码行的角度来看 ps 和 /proc/$PID/cmdline 可能是相同的,但 ps 在幕后还有很多事情要做。
【讨论】:
proc 文件系统导出此(和其他)信息。 查看 /proc/PID/cmd 符号链接。
【讨论】:
这对我有用:
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
【讨论】: