从 Python 中查找 Linux 中特定 PID 的命令
我想知道是否可以找出 PID 设置的“命令”。当我说命令时,我指的是当您在 Linux shell 中运行命令“top”时在最后一栏中看到的内容。当我有特定的 PID 时,我想以某种方式从 Python 获取这些信息。
任何帮助都会很棒。谢谢。
I'd like to know if it's possible to find out the "command" that a PID is set to. When I say command, I mean what you see in the last column when you run the command "top" in a linux shell. I'd like to get this information from Python somehow when I have a specific PID.
Any help would be great. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这对我有用:
This worked for me:
使用 /proc 文件的缺点是可移植性较低,这可能是也可能不是一个问题。下面是如何使用标准 shell 命令来实现这一点。
注意两个
-w
选项,它们指示 ps 不要截断输出(默认情况下会截断输出)。从 python 读取其输出就像调用单个函数
subprocess.check_output()
记录在此处。Using a /proc files has a disadvantage of lower portability, which may or may not be a concern. Here's how you can use the standard shell command for that
Note the two
-w
options that instructs ps to not truncate the output (which it does by default)Reading its output from python is as simple as calling a single function
subprocess.check_output()
documented here.一个有趣的 Python 包是 psutil。
例如,要获取特定 PID 的命令:
最后一行将打印类似
['/usr/bin/python', 'main.py']
的内容。获取此信息的更可靠方法是,如果 pid 表示不再运行的进程,请小心:
An interesting Python package is psutil.
For example, to get the command for a specific PID:
The last line will print something like
['/usr/bin/python', 'main.py']
.A more robust way to get this information, being careful if the pid represents a process no longer running:
查看
/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)
”。另外,作为文本段的程序并不总是您想要的。例如,上面的
/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) 而不是 pipeline(2)、fork(2)、execve(2)、readdir(3) 来读取它...,写(2),读(2)。虽然 ps 和/proc/$PID/cmdline
从 Python 代码行的角度来看可能是相同的,但 ps 的幕后还有更多的事情要做。Look in
/proc/$PID/cmdline
, and then os.readlink() on/proc/$PID/exe
./proc/$PID/cmdline
is not necessarily going to be correct, as a program can change its argument vector or it may not contain a full path. Three examples of this from my current process list are: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
That first one is obvious - it's not a valid path or program name. The second is just an executable with no path name. The third looks ok, but that whole command line is actually in
argv[0]
, with spaces separating the arguments. Normally you should have NUL separated arguments.All this goes to show that
/proc/$PID/cmdline
(or the ps(1) output) is not reliable.However, nor is
/proc/$PID/exe
. Usually it is a symlink to the executable that is the main text segment of the process. But sometimes it has "(deleted)
" after it if the executable is no longer in the filesystem.Also, the program that is the text segment is not always what you want. For instance,
/proc/$PID/exe
from that/usr/sbin/postgrey
example above is/usr/bin/perl
. This will be the case for all interpretted scripts (#!).I settled on parsing
/proc/$PID/cmdline
- taking the first element of the vector, and then looking for spaces in that, and taking all before the first space. If that was an executable file - I stopped there. Otherwise I did a readlink(2) on/proc/$PID/exe
and removed any "(deleted)
" strings on the end. That first part will fail if the executable filename actually has spaces in it. There's not much you can do about that.BTW. The argument to use ps(1) instead of
/proc/$PID/cmdline
does not apply in this case, since you are going to fall back to/proc/$PID/exe
. You will be dependent on the/proc
filesystem, so you may as well read it with read(2) instead of pipe(2), fork(2), execve(2), readdir(3)..., write(2), read(2). While ps and/proc/$PID/cmdline
may be the same from the point of view of lines of python code, there's a whole lot more going on behind the scenes with ps.阅读
ps
命令并解析它的输出。应该这样做
Read up on the
ps
command and parse its output.should do it
查看 /proc/$PID/cmdline
Look in
/proc/$PID/cmdline
proc 文件系统导出此(和其他)信息。
查看 /proc/PID/cmd 符号链接。
The proc filesystem exports this (and other) information.
Look at the /proc/PID/cmd symlink.