STK
STK

Reputation: 162

How to create new console sessions in Python and work with them

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

Answers (2)

Sylvain Leroux
Sylvain Leroux

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:

toto

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

Eric Thomas
Eric Thomas

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

Related Questions