How to programatically read/write to an interactive python shell - python

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.

Related

Trying to launch subprocess from macro

I am trying to launch a python subprocess from excel using PYXLL, but it seems to have trouble launching the cmd window and running commands.
Below is a sample of what I am trying to run:
#xl_macro()
def test():
if 1 == 1:
xlcAlert("Next line nothing happens") #Popup appears
p = subprocess.Popen(r'start cmd /k', shell=True, creationflags=subprocess.CREATE_NEW_CONSOLE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
xlcAlert("{}".format(p.pid)) #p was never launched
I am trying to capture values from excel and pass them in a subprocess. This works when executing in my IDE: data is read from excel and then subprocess launches window. However, once adding the decorator to have it run as macro in EXCEL, the script will just stop once subprocess.Popen line is reached. Is there any way to launch a subprocess from pyxll?
After investigation, and thanks to Charles Duffy, Microsoft Office SandBoxing kills the shell subprocess. This has been implemented for security reasons in latest versions.
The simple solution is to run subprocess with shell=False and pass the args in a list:
p1 = subprocess.Popen(cmdlist, shell=False)
The Sandboxing will not terminate the process - python window will open while script is running.

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')

Running a Python print statement containing a bash command [duplicate]

This question already has answers here:
How do I execute a program or call a system command?
(65 answers)
Closed 5 years ago.
Is there a way for the Python print statement containing a bash command to run in the terminal directly from the Python script?
In the example below, the awk command is printed on the terminal.
#!/usr/bin/python
import sys
print "awk 'END{print NF}' file"
I can of course think of writing the print statement in a separate file and run that file as a bash script but is there a way to run the awk command directly from the python script rather than just printing it?
is there a way to run the awk command directly from the python script rather than just printing it?
Yes, you can use subprocess module.
import subprocess
subprocess.call(["ls", "-l"])
You can pipe your Python output into a Bash process, for example,
python -c "print 'echo 5'" | bash
will output
5
You could even use the subprocess module to do that from inside Python, if you wanted to.
But I am sure this is pretty bad design, and not a good idea. If you get your coding wrong, there's a risk you could allow hostile users to execute arbitrary commands on the machine running your code.
One solution is to use subprocess to run a shell command and capture its output, for example:
import subprocess
command = "awk 'END{print NF}' file"
p = subprocess.Popen([command], shell=True, bufsize=2000,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
print(''.join([line for line in child_stdout]))
child_stdout.close()
p.stdout.close()
Adjust bufsize accordingly based on the size of your file.

How to automate interactive console applications in 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()

Linux commands in Python subprocesses

I'm executing a set of commands that first require me to call bash. I am trying to automate these commands by writing a Python script to do this. My first command obviously needs to be bash, so I run
p = subprocess.call(['bash'])
and it launches the bash shell no problem.
Where I then have problems is trying to execute the remaining code in the bash environment. I thought perhaps there was a need for process communication (i.e. redirecting stdout as in
p0 = subprocess.Popen(cmd, stdout=subprocess.PIPE)
p1 = subprocess.Popen(['bash'], stdin=p0.stdout)
p1.communicate()
) but the piping doesn't seem to solve my problem.
How can I write this script so that it mimics the following sequential Linux commands?
$ bash
$ cmd1
$ cmd2
...
I'm working with Ubuntu 14.04 and Python 2.7.6.
Thanks in advance for the guidance!
import subprocess
def bash_command(cmd):
subprocess.Popen(cmd, shell=True, executable='/bin/bash')
bash_command('[your_command]')
You don't need to call run bash separately. You can run something like:
p1 = subprocess.call(['cmd1'])
p2 = subprocess.call(['cmd2'])
If you must run bash for some reason (the commands contain bash statements, for example), you can run bash -c "cmd1; cmd2" from subprocess.call().
Edit: As Busturdust pointed out, you can also try setting shell=True, but that uses sh, not bash. But that may be enough for you.

Categories

Resources