简体   繁体   中英

Sending commans on sub process in python

I just want to build a little python music client on my raspberry pi. I installed "mpg321" and it works great but now my problem. After sending the command

os.system("mpg321 -R testPlayer")

python waits for user input like play, pause or quit. If I write this in my terminal the player pause the music oder quits. Perfect but I want python to do that so I send the command

os.system("LOAD test.mp3")

where LOAD is the command for loading this mp3. But nothing happens. When I quit the player via terminal I get the error:

sh: 1: LOAD: not found

I think this means that

os.system("mpg321 -R testPlayer")

takes the whole process and after I quit it python tries to execute the comman LOAD. So how do I get these things work together?

My code:

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")

Thanks for your help!

First, you should almost never be using os.system . See the subprocess module.

One major advantage of using subprocess is that you can choose whatever behavior you want—run it in the background, start it and wait for it to finish (and throw an exception if it returns non-zero), interact with its stdin and stdout explicitly, whatever makes sense.

Here, you're not trying to run another command "LOAD test.mp3" , you're trying to pass that as input to the existing process. So:

p = subprocess.Popen(['mpg321', '-R', 'testPlayer'], stdin=PIPE)

Then you can do this:

p.stdin.write('LOAD test.mp3\n')

This is roughly equivalent to doing this from the shell:

echo -e 'LOAD test.mp3\n' | mpg321 -R testPlayer

However, you should probably read about communicate , because whenever it's possible to figure out how to make your code work with communicate , it's a lot simpler than trying to deal with generic I/O (especially if you've never coded with pipes, sockets, etc. before).

Or, if you're trying to interact with a command-line UI (eg, you can't send the command until you get the right prompt), you may want to look at an "expect" library. There are a few of these to choose from, so you should search at PyPI to find the right one for you (although I can say that I've used pexpect successfully in the past, and the documentation is full of samples that get the ideas across a lot more quickly than most expect documentation does).

You are looking for a way to send data to stdin . Here is an example of this using Popen:

from subprocess import Popen, PIPE, STDOUT

p = Popen(['mpg321', '-R testPlayer'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)

mpg123_stdout = p.communicate(input='LOAD test.mp3\n')[0]
print(mpg123_stdout)

You establish pointers to stdin and stdout , then after you start your process, you communicate with stdin and read from stdout . Be sure to send new lines (carriage returns)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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