【问题标题】:subprocess.Popen(cl, ..., shell=True) does not work like a shell command forwardersubprocess.Popen(cl, ..., shell=True) 不像 shell 命令转发器那样工作
【发布时间】:2019-09-25 20:53:57
【问题描述】:

我的目标是让 pico2wave 用 python 说话。

我的代码

cl = 'pico2wave --lang=de-DE --wave=/tmp/test.wav "Test"'
print(cl)
tempFile = '/dev/null'
with open(tempFile, "w+") as f:
  process = subprocess.Popen(cl, stdout=f, shell=True)
  cl = 'aplay /tmp/test.wav'
  print(cl)
  process = subprocess.Popen(cl, stdout=f, shell=True) 
  cl = 'rm -f /tmp/test.wav'
  print(cl)
  process = subprocess.Popen(cl, stdout=f, shell=True) 

在命令行中使用打印输出就可以了。但是对于 python 代码,它不会。为什么?

【问题讨论】:

    标签: python python-2.7 subprocess


    【解决方案1】:

    您没有等待任何进程完成。为了使其等同于一个一个地运行 shell 命令,您需要在每个 Popen 之后调用一个 process.wait() 以便命令在您启动下一个进程之前完成。在这种情况下,aplay 依赖于pico2wave 写出aplay 的输入,并依赖于rm 在有机会打开它并读取内容之前不将其删除。

    没有process.wait(),就像在shell中运行(注意后台&):

    pico2wave --lang=de-DE --wave=/tmp/test.wav "Test" &
    aplay /tmp/test.wav &
    rm -f /tmp/test.wav &
    

    它引入了各种可怕的竞争条件。

    【讨论】:

    • @VitalisHommel:Yar。如果您想等待进程并确保它们成功完成,您可能希望从使用Popen 切换到使用subprocess.check_call,它会等待您,如果命令具有非 0 退出状态(表示失败)。您的原始代码不会有任何其他变化,每次看到它时您只需将 Popen 更改为 check_call
    猜你喜欢
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    相关资源
    最近更新 更多