Page 1 of 1

running system command from python.

Posted: Wed Nov 02, 2016 2:57 pm
by KeithSloan
I am trying to run a system command from python.
The command I wish to run is echo "Some Text" | festival --tts
Python doc says system calls are all depreciated in favour of subprocess but I don't seem to be able to get subprocess to work, I assume because of the pipe

Re: running system command from python.

Posted: Wed Nov 02, 2016 3:52 pm
by Paeryn
KeithSloan wrote:I am trying to run a system command from python.
The command I wish to run is echo "Some Text" | festival --tts
Python doc says system calls are all depreciated in favour of subprocess but I don't seem to be able to get subprocess to work, I assume because of the pipe
Maybe something like :-

Code: Select all

import subprocess

with subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE, universal_newlines=True) as festival:
    festival.communicate("Some Text");
Or

Code: Select all

import subprocess

subprocess.call('echo "Some Text" | festival --tts', shell=True);
I'd prefer the first way, better than passing the string to a shell.

Re: running system command from python.

Posted: Thu Nov 03, 2016 3:32 pm
by KeithSloan
Tried

Code: Select all

                        with subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE, universal_newlines=True) as festival:
                                festival.communicate(l);
But got

Code: Select all

Traceback (most recent call last):
  File "LetterBoard.py", line 123, in <module>
    with subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE, universal_newlines=True) as festival:
AttributeError: __exit__

Re: running system command from python.

Posted: Thu Nov 03, 2016 4:07 pm
by Paeryn
Ahh, you're using python2 then (it works in python3), looks like you can't put it in a with clause in python2. Try

Code: Select all

import subprocess

festival = subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE, universal_newlines=True)
festival.communicate("Some Text");
Or even (if you like long lines)

Code: Select all

import subprocess

subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE, universal_newlines=True).communicate("Some Text");
The universal_newlines=True bit allows sending normal strings via communicate(), if you omit it then you send and receive byte strings (it also converts any '\n' into the default line separator when sending and vice versa when receiving), e.g.

Code: Select all

import subprocess

festival = subprocess.Popen(["festival", "--tts"], stdin=subprocess.PIPE)
festival.communicate(b"Some Text");

Re: running system command from python.

Posted: Thu Nov 03, 2016 4:52 pm
by KeithSloan
Okay now get two error messages
xcb_connection_has_error() returned true
xcb_connection_has_error() returned true

Also what is the correct way to close the spawned process down.

Re: running system command from python.

Posted: Thu Nov 03, 2016 6:06 pm
by Paeryn
KeithSloan wrote:Okay now get two error messages
xcb_connection_has_error() returned true
xcb_connection_has_error() returned true

Also what is the correct way to close the spawned process down.
No idea on the xcb messages, something that uses xcb is issuing that, festival maybe? I've never used festival so I don't know anything about it.

As to closing the process, communicate() waits for the process to finish before returning, as long as festival quits when it's finished then you don't need to do anything.

Re: running system command from python.

Posted: Thu Nov 03, 2016 8:06 pm
by KeithSloan
Googling for the error message xcb_connection error I found that it seemed to be something to do with pulse audio.

On trying to debug took me back to trying festival from the command line and got the same two error messages. A reboot seems to have cleared the problem.

Thanks for all your help.