获取在 Python 子进程中终端内执行的命令的进程 ID [英] Get process ID of command executed inside terminal in Python subprocess

查看:32
本文介绍了获取在 Python 子进程中终端内执行的命令的进程 ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Python 子进程中的 gnome-terminal 中运行 vim:

<预><代码>>>>导入子流程>>>cmd=['gnome-terminal', '--', 'vim']>>>p = subprocess.Popen(cmd)

可以使用 p.pid 获取 gnome-terminal 的进程 ID,但是如何从 Python 脚本中获取 vim 的进程 ID?

尽管 Bash 中的 pstree 将 vim 显示为 gnome-terminal 的子进程,但 psutils 并未列出它.

<预><代码>>>>导入 psutil>>>terminal_process = psutil.Process(p.pid)>>>terminal_process.children()[]

解决方案

我认为这很好

导入时间导入子流程cmd=['gnome-terminal','--', 'vim']p = subprocess.Popen(cmd)时间.睡眠(10)a = subprocess.Popen(['ps', '-eo', 'pid,ppid,command'], stdout = subprocess.PIPE)b = subprocess.Popen(['grep', 'vim'], stdin = a.stdout, stdout = subprocess.PIPE)输出,错误 = b.communicate()output = output.decode("utf-8").split('\n')打印(输出)

我使用 time.sleep(10) 的原因是因为某些原因 vim 没有被分叉那么快,所以我延迟了 10 秒.
这里我们创建了 2 个获取 vim 编辑器 ID 的进程,我们使用 stdout 和 stdin 将进程 a 的输出提供给 b.

然后我们使用.communicate()将进程b的stdout放入output.
现在我们的 output 是字节的形式,所以我们使用 .decode("utf-8") 将其解码为 UTF-8,然后在每一个新行上拆分.
它产生输出:

rahul@RNA-HP:~$ python3 so.py# _g_io_module_get_default: 为‘gio-vfs’找到默认实现 gvfs (GDaemonVfs)# _g_io_module_get_default: 为‘gsettings-backend’找到默认实现 dconf (DConfSettingsBackend)# watch_fast: "/org/gnome/terminal/legacy/"(建立:0,活动:0)# unwatch_fast: "/org/gnome/terminal/legacy/"(活动:0,建立:1)# watch_builted: "/org/gnome/terminal/legacy/" (建立: 0)['21325 21093 vim', '21330 21318 grep vim', '']拉胡尔@RNA-HP:~$

要验证这一点:

rahul@RNA-HP:~$ ps aux |grep gnome 终端拉胡尔 21093 1.7 2.4 978172 45096 ?Ssl 19:55 0:02/usr/lib/gnome-terminal/gnome-terminal-serverrahul 21374 0.0 0.0 8988 840 pts/0 S+ 19:57 0:00 grep --color=auto gnome-terminalrahul@RNA-HP:~$ ps -eo pid,ppid,command |grep vim21325 21093 vim21376 21104 grep --color=auto vim拉胡尔@RNA-HP:~$

这里我们可以看到vim是从gnome-terminal分叉出来的21093是gnome-terminal的id,也就是vim的ppid.

现在,如果我不使用 time.sleep(10)

rahul@RNA-HP:~$ python3 so.py['21407 21406/usr/bin/python3/usr/bin/gnome-terminal -- vim', '21409 21406 grep vim', '']

如果我们尝试验证这些 PID 是否存在:

rahul@RNA-HP:~$ kill 21407bash: kill: (21407) - 没有这样的过程拉胡尔@RNA-HP:~$

由于某种原因,这些 ID 不存在.
如果有多个vim实例:它产生:

 ['21416 21093 vim', '21736 21093 vim', '21738 21728 grep vim', '']


获取最新实例化的 vim pid:

output = output[len(output) - 3]

我们的输出按pid的升序排序,我们的最后一个和倒数第二个值是grep vim,所以我们需要倒数第三个参数来获取vim的pid.
评论是否可以改进.

I run vim inside gnome-terminal in a Python subprocess:

>>> import subprocess
>>> cmd=['gnome-terminal', '--', 'vim']
>>> p = subprocess.Popen(cmd)

It is possible to get the process ID for gnome-terminal with p.pid, but how can I get the process ID for vim from within the Python script?

Even though pstree in Bash shows vim as a child process of gnome-terminal, psutils does not list it.

>>> import psutil
>>> terminal_process = psutil.Process(p.pid)
>>> terminal_process.children()
[]

解决方案

I think this works fine

import time
import subprocess

cmd=['gnome-terminal','--', 'vim']
p = subprocess.Popen(cmd)
time.sleep(10)

a = subprocess.Popen(['ps', '-eo', 'pid,ppid,command'], stdout = subprocess.PIPE)
b = subprocess.Popen(['grep', 'vim'], stdin = a.stdout, stdout = subprocess.PIPE)

output, error  = b.communicate()
output = output.decode("utf-8").split('\n')
print(output)

The reason I used time.sleep(10) is because for some reason vim was not getting forked that fast so, I delayed it for 10 seconds.
Here we create 2 process for getting the ID of vim editor, we give the output of process a to b using stdout and stdin.

Then we use .communicate() to get stdout of process b into output.
Now our output is in form of bytes so we decode it to UTF-8 using .decode("utf-8") and then split on every new line.
It produces the output:

rahul@RNA-HP:~$ python3 so.py
# _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
# _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’
# watch_fast: "/org/gnome/terminal/legacy/" (establishing: 0, active: 0)
# unwatch_fast: "/org/gnome/terminal/legacy/" (active: 0, establishing: 1)
# watch_established: "/org/gnome/terminal/legacy/" (establishing: 0)
['21325 21093 vim', '21330 21318 grep vim', '']
rahul@RNA-HP:~$ 

To verify this:

rahul@RNA-HP:~$ ps aux | grep gnome-terminal
rahul    21093  1.7  2.4 978172 45096 ?        Ssl  19:55   0:02 /usr/lib/gnome-terminal/gnome-terminal-server
rahul    21374  0.0  0.0   8988   840 pts/0    S+   19:57   0:00 grep --color=auto gnome-terminal
rahul@RNA-HP:~$ ps -eo pid,ppid,command | grep vim
21325 21093 vim
21376 21104 grep --color=auto vim
rahul@RNA-HP:~$ 

Here we can see that vim is forked from gnome-terminal 21093 is the id of gnome-terminal which is the ppid of vim.

Now, this happened if I didn't use time.sleep(10)

rahul@RNA-HP:~$ python3 so.py
['21407 21406 /usr/bin/python3 /usr/bin/gnome-terminal -- vim', '21409 21406 grep vim', '']

If we try to verify if those PID exist:

rahul@RNA-HP:~$ kill 21407
bash: kill: (21407) - No such process
rahul@RNA-HP:~$ 

Those ID dont exist for some reason.
If there are multiple instances of vim: It produces:

 ['21416 21093 vim', '21736 21093 vim', '21738 21728 grep vim', '']


To get the latest instantiated vim's pid:

output = output[len(output) - 3]

Our output is sorted in ascending order of pid's and our last and second last values are and grep vim so we need the third last argument for getting the pid of vim.
Comment if something can be improved.

这篇关于获取在 Python 子进程中终端内执行的命令的进程 ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆