I use this script to run interactive VLC bash:
import os
import sys
if len(sys.argv) > 1:
tmp = os.popen('vlc -I rc --novideo --noaudio --rc-fake-tty -q udp://@1.2.3.4:1234').read()
else :
print "Error: no input"
now in this bash opend I like to run 'info' command, How to do this?
if in bash I type
vlc -I rc --novideo --noaudio --rc-fake-tty -q udp://@1.2.3.4:1234
It shows this
VLC media player 2.0.8 Twoflower (revision 2.0.8a-0-g68cf50b)
VLC media player 2.0.8 Twoflower
Command Line Interface initialized. Type `help' for help.
>
and It wait for get a command.
This can be done with pure pipes, but it's going to be hard. And even harder if you use os.popen()
instead of using subprocess
.
The right way to script an interactive program is to use a higher-level library that's designed to make it easy, like pexpect
. Then you just write something like:
import pexpect
child = pexpect.spawn('vlc -I rc --novideo --noaudio --rc-fake-tty -q udp://@1.2.3.4:1234')
child.expect('>')
child.sendline('info')
response = child.before
However, a much better solution is to not run VLC in interactive mode; just run it in batch mode and pass it commands. Going out of your way to have it treat your input as a TTY just so you can try to figure out how to act like a human at a TTY is making things harder for no good reason.
Or, even better, use libVLC instead. As you can see from that link, there are Python bindings for it.
If you really want to do it interactively, and you want to do it manually over pipes, you will have to be very careful. If you don't mind just deadlocking on any unexpected results, you can do something like this:
import subprocess
child = subprocess.Popen(['vlc', '-I', 'rc', '--novideo', '--noaudio',
'--rc-fake-tty', '-q', 'udp://@1.2.3.4:1234'],
stdin=PIPE, stdout=PIPE)
def split_on_prompts():
rbuf = ''
while True:
newbuf = child.stdout.read()
rbuf += newbuf
out, prompt, rest = rbuf.partition('\n>')
if prompt:
yield out
rbuf = rest
if not newbuf:
yield rest
return
output = split_on_prompts()
banner = next(output)
child.stdin.write('info\n')
response = next(output)
# etc.
As you can see, this is a lot less fun.
And if you insist on using os.open
instead even though it's deprecated and even more painful to use, you obviously can't write to it if you open the pipe in the default 'r'
mode, just like any other file-like object, and of course tacking .read()
on the end means you don't even have the popen
object anymore, you just stored the first buffer it gave you and then leaked the handle. If you change that to open in 'r+'
mode, if that works on your platform, and you store the popen
object itself, you can use it similarly to the subprocess.Popen
object above, using child.write
and child.read
instead of child.stdin.write and
child.stdout.read`.
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.