How to automate interactive console applications in Python? - python

I want to control running process/program by script in Python.
I have a program `linphonec´ (You can install: apt-get install linphonec).
My task is:
Run linphonec (I'm using subprocess at the moment)
When linphonec is running it has many commands to control this and I want to e.g use proxy list (command in linphonec).
Simple flow:
test#ubuntu$ > linphonec
linphonec > proxy list
How can I do this?

There are actually 2 ways to communicate:
Run your program with myprogram.py | linphonec to pass everything you print to linphonec
Use subprocess.Popen with subprocess.PIPE in constructor via keywrod-args for stdin (propably stdout and stderr, too) and then communicate for a single command or use stdin and stdout (stderr) as files
import subprocess
p=subprocess.Popen("linphonec",
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True) #this is for text communication
p.stdin.write("proxy list\n")
result_first_line=p.stdout.readline()

Related

Displaying images in linux terminal using Python

I am trying to use w3mimgdisplay to display images on the image terminal, and was looking at the source code for Ranger file manager. The file I was looking at can be found here.
Using this, I made a simple program.
import curses
from subprocess import Popen, PIPE
process = Popen("/usr/libexec/w3m/w3mimgdisplay",
stdin=PIPE, stdout=PIPE, universal_newlines=True)
process.stdin.write("echo -e '0;1;100;100;400;320;;;;;picture.jpg\n4;\n3;'")
process.stdin.flush()
process.stdout.readline()
process.kill()
Whenever I enter
echo -e '0;1;100;100;400;320;;;;;picture.jpg\n4;\n3;' \ /usr/libexec/w3m/w3mimgdisplay
into the terminal, it prints the image properly, however, running the python script does nothing. How can I write the output of the program to the terminal?
the shell echo command adds newline to the end of its output (unless you use the -n switch which you didn't) so you need to mimic that by adding a newline at the end of your command too.
Also, you should write the string contents, not the echo command itself, because this is being sent directly to the w3mimgdisplay process, not to the shell.
I'm also unsure why readline. I suggest using the .communicate() command instead because it makes sure you don't get into a rare but possible read/write buffer race condition. Or, the best method, use the simpler subprocess.run() directly:
import subprocess
subprocess.run(["/usr/libexec/w3m/w3mimgdisplay"],
input=b'0;1;100;100;400;320;;;;;picture.jpg\n4;\n3;\n')

Kill external process on pythonw.exe

In Python, external processes can be started easily using the subprocess module. For instance on Windows:
command = 'external_app'
my_process = subprocess.Popen(
command,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,
shell=True,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
universal_newlines=True)
To kill the process, we can run:
os.kill(my_process.pid, signal.CTRL_BREAK_EVENT)
This works fine using the command-line interpreter of Python (python.exe). But if I like to start and stop processes from within a graphical Python application without a command-line window using pythonw.exe the problem occurs that I can’t stop the process with os.kill anymore.
How can I kill an external process on Windows with pythonw.exe?

How to launch idlex from virtualenv through python script

I am trying to automate a couple of steps I have to do repeatedly on windows, like open command prompt and starting virtualenv and then launching idlex. I am writing a python script which I can double click to automatically perform both these steps. I read this answer but couldn't understand it. Below is the script I have written where I am making two calls to Popen
import subprocess
#launches virtualenv in command prompt
proc1 = subprocess.Popen('start\
"IDLE"\
/d c:\\Python27\\fp\
/wait\
C:\\Python27\\fp\\Scripts\\activate.bat',
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
#starts idlex
proc2 = subprocess.Popen('start\
"IDLE"\
/B\
/d c:\\Python27\\fp\
/wait\
c:\\Python27\\fp\\scripts\\python.exe\
C:\\Python27\\fp\\Scripts\\idlex.py',
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
I want to perform both these steps without making second Popen call, but communicate() isn't working and I don't understand why. Is it because start spawns another process whose handle isn't available?

How to programatically read/write to an interactive python shell

I want to write some commands to a python shell and read the output using the Popen code below -
from subprocess import Popen,PIPE
p = Popen(["python"], stdin=PIPE, stdout=PIPE, shell=True)
out, err = p.communicate("help()\n")
print out.rstrip()
But it doesn't print anything I normally see when I run the help() command in python. What am I missing? Note that I'm using python here as an example, I want to communicate with interactive programs in general using python code.

run a process in another terminal

I'm actually running a subprocess from a python program using Popen
proc= subprocess.Popen("xterm -e python script.py", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
And when this process is running on xterm, we can kill it using Ctrl+C, is there a way to send other signals using (Ctrl+Z and fg,...) to resume and continue the job?
Another solution would be running this process in another terminal, without using xterm -e is this possible?
Any other solution would be helpful.
Thanks
You could do it programatically in psutil
import psutil
p = psutil.Pocesss(proc.pid)
p.suspend()
p.resume()
With Python2.6+
# send ctrl+c
popen.send_signal(signal.SIGINT)

Categories

Resources