简体   繁体   English

如何让Popen等待命令完成?

[英]How to make Popen wait so the command finishes?

The objective is that a command is launched in a bash shell with Popen, and then the output of this command is passed to a variable, but Popen should wait until the command finishes before moving on, which doesn't happen. 目的是使用bopen在bash shell中启动命令,然后将该命令的输出传递给变量,但是Popen应该等到命令完成后再继续操作,否则不会发生。

I tried using call instead of Popen, but call doesn't output anything but the exit code, which isn't ideal. 我尝试使用call代替Popen,但是call除了退出代码外没有输出任何东西,这不是理想的选择。 I tried using wait() too, but I get an error. 我也尝试使用wait(),但出现错误。

var1 = Popen(["command | grep 'stuff' | cut -d 'delimiter' -f3"], 
             shell=True, stdout=PIPE,
             universal_newlines=True).communicate()[0].rstrip()
var2 = Popen(["command | grep 'stuff' | cut -d 'delimiter' -f1"], 
             shell=True, stdout=PIPE,
             universal_newlines=True).communicate()[0].rstrip()
print(var1 + var2)

Python prints var1 correctly, but not var2, which is None because it was not assigned by anything since the command didn't run or wasn't allowed time to finish. Python可以正确打印var1,但是不能正确打印var2,这是None,因为命令未运行或没有时间完成,所以它没有被任何东西分配。 Running the var2 command directly on the terminal, exactly as in the python program, yields the desired results, but when python tries to run it, it simply skips it and prints var1 and var2, but only the var1 string is displayed, var2 is completely ignored. 像在python程序中一样,直接在终端上运行var2命令会产生所需的结果,但是当python尝试运行它时,它只是跳过了它并显示var1和var2,但是只显示了var1字符串,因此var2完全忽略了。

The AttributeError: 'str' object has no attribute 'wait' error occurs because the communicate() method returns a tuple of (stdout, stderr) strings. AttributeError: 'str' object has no attribute 'wait'错误发生,因为communicate()方法返回了(stdout, stderr)字符串的元组。 wait() is a method on the Popen object itself. wait()Popen对象本身的方法。 You don't need to call wait() if you use communicate() , since it will do the wait for you. 如果您使用communicate() ,则无需调用wait() communicate() ,因为它将为您做等待。 And you can't call wait() on the Popen object if you throw away the only reference to it. 如果丢弃唯一的引用,则不能Popen对象上调用wait()

That said, do you really need to use grep and cut to accomplish the job? 也就是说,您真的需要使用grepcut来完成这项工作吗? Something like this is likely going to be faster and less likely to contain a security bug: 这样的事情可能会更快,并且不太可能包含安全漏洞:

p = Popen(['command'], stdout=PIPE, universal_newlines=True)
result = []
for line in p.stdout:
    if 'stuff' in line:
        value = line.split('delimiter')[4]
        result.append(value)

You have to pass the command as a string, or parse it into tokens yourself. 您必须将命令作为字符串传递,或者自己将其解析为令牌。 You'll want to use subprocess.run instead of the low-level Popen . 您将要使用subprocess.run而不是低级的Popen Trivially 琐碎地

var = subprocess.run("command | grep 'stuff' | cut -d 'delimiter' -f3", 
         shell=True, stdout=PIPE,
         universal_newlines=True).stdout

A much better solution is to replace grep and cut with Python code, and get rid of the shell=True as a useful bonus. 更好的解决方案是用Python代码替换grepcut ,并摆脱shell=True作为有用的奖励。

var = list()
output = subprocess.run(["command"], stdout=PIPE, universal_newlines=True)
for line in output.stdout.split('\n'):
    if 'stuff' in line:
        var.append(line.split('delimiter')[2])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM