Reputation: 162
I'm trying to figure out how to work with consoles in Python. Let's say, I have a Python2 script. And this script should create 3 consoles (bash or any other) and provide different commands to them.
Example:
What I've found so far is subprocess module.
I can use this
import subprocess
term1 = subprocess.Popen(['open', '-a', 'Terminal'])
But I still cannot find how to send a command to term1
Thank you.
Upvotes: 1
Views: 3761
Reputation: 51990
I've tested that using xterm
on Linux. Might be adapted to MacOS X terminal without too much problems ... I hope.
The key idea is to create an anonymous pipe from Python, then instruct the shell running inside of the terminal emulator to read from that pipe:
import os
output, input = os.pipe()
term = subprocess.Popen("xterm -e 'bash </dev/fd/{}'".format(output),shell=True)
f = os.fdopen(input,"wt")
# output as much as command as you want. `flush` between them ... to flush data
f.writelines("echo toto\n")
f.flush()
f.close()
Producing that output on the GUI terminal emulator:
If you want read and write, you have to open two pipes -- but beware of dead-lock if you fill the pipe in one direction:
>>> import os
>>> output1, input1 = os.pipe()
>>> output2, input2 = os.pipe()
>>> term = subprocess.Popen("xterm -e 'bash </dev/fd/{} >/dev/fd/{}'".format(output1,input2),shell=True)
>>>
>>> fin = os.fdopen(input1,"wt")
>>> fout = os.fdopen(output2,"rt")
>>>
# FOR EXPERIMENTAL PURPOSE ONLY: SUBJECT TO DEAD-LOCK !!!
>>> fin.writelines("date\n")
>>> fin.flush()
>>>
>>> print fout.readline()
Thu Aug 14 23:50:15 CEST 2014
>>>
>>> fin.close()
>>> fout.close()
That being said, in that configuration, the only interest in having a terminal opened is to display potential stderr output on the GUI display.
If you only need to communicate with the underlying command (bash, ping, ...), you don't really need a terminal, just to connect to the corresponding subprocess standard I/O as explained in an other answer.
Upvotes: 2
Reputation: 717
If you want to have the ability to communicate with your subprocess its best to use subprocess.popen
.
https://docs.python.org/2/library/subprocess.html#subprocess.Popen
This way you can create a stdin and stout to communicate with the process. As shown in the link above you simply add them to the popen argument:
subprocess.Popen(args, stdin=PIPE, stdout=PIPE)
There is also popen.communicate(input= 'your input')
.
That will wait for the command to finish.
Upvotes: 1