在python中的子进程上发送commans

emh*_*mha 0 python subprocess

我只想在我的覆盆子pi上建立一个小蟒蛇音乐客户端.我安装了"mpg321",它运行良好,但现在我的问题.发送命令后

os.system("mpg321 -R testPlayer")
Run Code Online (Sandbox Code Playgroud)

python等待播放,暂停或退出等用户输入.如果我在终端中写这个,播放器暂停音乐或退出.完美,但我希望python这样做,所以我发送命令

os.system("LOAD test.mp3")
Run Code Online (Sandbox Code Playgroud)

其中LOAD是加载此mp3的命令.但没有任何反应.当我通过终端退出播放器时,我收到错误消息:

sh: 1: LOAD: not found
Run Code Online (Sandbox Code Playgroud)

我认为这意味着

os.system("mpg321 -R testPlayer")
Run Code Online (Sandbox Code Playgroud)

采取整个过程,在我退出之后,python尝试执行comman LOAD.那么我如何让这些东西一起工作呢?

我的代码:

import os

class PyMusic:
    def __init__(self):
        print "initial stuff later"

    def playFile(self, fileName, directory = ""):
        os.system("mpg321 -R testPlayer")
        os.system("LOAD test.mp3")


if __name__ == "__main__":
    pymusic = PyMusic()
    pymusic.playFile("test.mp3")
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!

aba*_*ert 5

首先,你几乎不应该使用os.system.请参阅子进程模块.

使用的一个主要优点subprocess是,你可以选择在后台的任何行为,你想运行它,启动它,并等待其完成(如果返回非零抛出一个例外),因为它的互动stdinstdout明确的,不管是什么让感.

在这里,您不是要尝试运行另一个命令"LOAD test.mp3",而是尝试将其作为输入传递给现有进程.所以:

p = subprocess.Popen(['mpg321', '-R', 'testPlayer'], stdin=PIPE)
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

p.stdin.write('LOAD test.mp3\n')
Run Code Online (Sandbox Code Playgroud)

这大致等同于从shell执行此操作:

echo -e 'LOAD test.mp3\n' | mpg321 -R testPlayer
Run Code Online (Sandbox Code Playgroud)

但是,您应该阅读有关通信的内容,因为只要有可能弄清楚如何使代码工作communicate,这比尝试处理通用I/O要简单得多(特别是如果您从未编写过管道,套接字,之前).

或者,如果您尝试与命令行UI进行交互(例如,在获得正确的提示之前无法发送命令),您可能需要查看"期望"库.有一些可供选择,所以你应该在PyPI搜索找到合适的一个(虽然我可以说我过去成功使用过pexpect,文档中充满了获得想法的样本)比大多数expect文档更快地跨越很多).