【问题标题】:How to run " ps cax | grep something " in Python?如何在 Python 中运行“ps cax | grep something”?
【发布时间】:2023-03-23 09:31:01
【问题描述】:

如何运行带有管道 | 的命令?

子进程模块看起来很复杂...

有没有类似的

output,error = `ps cax | grep something`

在 shell 脚本中?

【问题讨论】:

  • 不要对subprocess 执行此操作。使用 shell 执行此操作要容易得多。事实上,这是 shell 最擅长的一件事。

标签: python command pipe


【解决方案1】:

Replacing shell pipeline:

import subprocess

proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)

proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
out, err = proc2.communicate()
print('out: {0}'.format(out))
print('err: {0}'.format(err))

PS。使用shell=True 可能很危险。例如,请参阅文档中的 the warning


还有 sh module 可以让 Python 中的子进程脚本编写更加愉快:

import sh
print(sh.grep(sh.ps("cax"), 'something'))

【讨论】:

  • 对 sh 模块的很好参考,我强烈推荐它。
  • sh.grep(sh.ps('aux', _piped=True), 'something') - 为我工作
  • @unutbu,你能详细解释一下为什么应该调用proc1.stdout.close()吗?
  • @SangminKi​​m:这似乎已在 Python3 中得到修复或解决,但至少在 Python2.7 中,如果您要在 @987654333 中生成一个长时间运行的进程,例如 find / -print @ 而不调用 proc1.stdout.close() 并在 proc2 中生成类似 head 的短运行命令,然后您会看到 find / -print 在对 head 的调用结束后仍然运行很长时间。包含proc1.stdout.close() 允许findhead 完成后不久结束。
  • 有关 SIGPIPE 的更多信息,请参阅 this commentthis postthis one too
【解决方案2】:

你已经接受了一个答案,但是:

你真的需要使用 grep 吗?我会写这样的:

import subprocess
ps = subprocess.Popen(('ps', 'cax'), stdout=subprocess.PIPE)
output = ps.communicate()[0]
for line in output.split('\n'):
    if 'something' in line:
        ...

这具有不涉及shell=True 及其风险的优点,不会分叉单独的 grep 进程,并且看起来非常像您编写用于处理数据文件类对象的那种 Python。

【讨论】:

  • 对我来说,output 是一个 [byte],必须像 str(output).split("\\n") 一样使用它
【解决方案3】:
import subprocess

process = subprocess.Popen("ps cax | grep something",
                             shell=True,
                             stdout=subprocess.PIPE,
                           )
stdout_list = process.communicate()[0].split('\n')

【讨论】:

【解决方案4】:

放下那个 'ps' 子进程并慢慢后退! :)

改用psutil 模块。

【讨论】:

  • 我想使用 psutil,但这个答案在没有说明如何完成的情况下并不是很有帮助。
  • 请分享示例
  • import psutil; for proc in psutil.process_iter(): cmdline = " ".join(proc.cmdline()); if something in cmdline: break
【解决方案5】:
import os

os.system('ps -cax|grep something')

如果你想用某个变量替换 grep 参数:

os.system('ps -cax|grep '+your_var)

【讨论】:

  • @Kirk Strauser,你不能得到输出吗?我已经在交互式 python 解释器中对其进行了测试,并将其作为脚本运行,它按预期工作(我的 python 版本是 2.7.1,如果有帮助的话)
  • os.system 只返回子进程的int退出码。如果您在交互式提示符下运行它并看到 ps 的输出,那是因为 ps 正在写入 stout。 Python 实际上并没有捕获该输出。自己尝试一下:运行a = os.system('ls')。您仍然会看到 ls 的输出,a 将为 0(假设 ls 没有因某种原因失败)。
  • 这是不安全的。如果your_var 由其他人设置,则此代码允许他们运行任何他们想要的命令。例如your_var = "a; echo you got hacked"
猜你喜欢
  • 2021-10-08
  • 2022-01-23
  • 1970-01-01
  • 2012-03-11
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多