executing an R script from python - python

I have an R script that makes a couple of plots. I would like to be able to execute this script from python.
I first tried:
import subprocess
subprocess.call("/.../plottingfile.R", shell=True)
This gives me the following error:
/bin/sh: /.../plottingfile.R: Permission denied
126
I do not know what the number 126 means. All my files are on the Desktop and thus I do not think that any special permissions would be needed? I thought that this error may have had something to do with cwd = none but I changed this and I still had an error.
Next I tried the following:
subprocess.Popen(["R --vanilla --args </.../plottingfile.R>"], shell = True)
But this too gave me an error with:
/bin/sh: Syntax error: end of file unexpected.
Most recently I tried:
subprocess.Popen("konsole | /.../plottingfile.R", shell = True)
This opened a new konsole window but no R script was ran. Also, I received the following error:
/bin/sh: /.../plottingfile.R: Permission denied
Thanks.

First thing first, make sure that you have your platttingfile.R script at a place where you can access. Typically it is the same directory.
I read in the internet that there is a utility that comes called RScript which is used to execute R script from the command line. So in order to run the script you would use python like this:
import subprocess
retcode = subprocess.call(['/path/to/RScript','/path/to/plottingfile.R'])
This would return the retcode 0 upon successful completion. If your plottingfile.R is returning some kind of an output, it will be thrown on STDOUT. If it pulling up some GUI, then it would come up.
If you want to capture stdout and stderr, you do it like this:
import subprocess
proc = subprocess.Popen(['/path/to/RScript','/path/to/plottingfile.R'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()

Shell error 126 is an execution error.
The permission denied implies that you have a "permission issue" specifically.
Go to the file and make sure R/Python is able to access it.
I would try this out first:
$sudo chmod 777 /.../plottingfile.R
If the code runs, give it the correct but less accessible permission.
If this doesn't work, try changing R to Rscript.

have you tried chmod u+x /pathTo/Rscript.R ?

something likes this work usually for me:
subprocess.Popen("R --vanilla /PATH/plottingfile.R", shell = True)

Related

Execute shell command using Python subprocess

I want to execute the following command via a python script:
sudo cat </dev/tcp/time.nist.gov/13
I can execute this command via the command line completely fine. However, when I execute it using subprocess, I get an error:
Command ['sudo','cat','</dev/tcp/time.nist.gov/13'] returned non-zero exit status 1
My code is as follows
import subprocess
subprocess.check_output(['sudo','cat','</dev/tcp/time.nist.gov/13'])
As I mentioned above, executing the command via the command line gives the desired output without any error. I am using the Raspbian Jessie OS. Can someone point me in the right direction?
You don't want to use subprocess for this at all.
What does this command really do? It uses a bash extension to open a network socket, feeds it through cat(1) to reroute it to standard output, and decides to run cat as root. You don't really need the bash extension, or /bin/cat, or root privileges to do any of this in Python; you're looking for the socket library.
Here's an all-Python equivalent:
#!/usr/bin/env python3
import socket
s = socket.create_connection(('time.nist.gov', 13))
try:
print(s.recv(4096))
finally:
s.close()
(Note that all of my experimentation suggests that this connection works but the daytime server responds by closing immediately. For instance, the simpler shell invocation nc time.nist.gov 13 also returns empty string.)
Give this a try:
import subprocess
com = "sudo cat </dev/tcp/time.nist.gov/13"
subprocess.Popen(com, stdout = subprocess.PIPE, shell = True)

Connecting in SSH in a Python script

I am connected to a first Raspberry Pi (172.18.x.x) in SSH and I would like to launch a script on the first RPI but the script is on another Raspberry Pi (192.168.x.x).
First, I did the configuration to connect without password to the second RPI from the first one.
When I am on the first one, I am launching this command :
ssh pi#192.168.x.x 'sudo python script_RPI2.py'
And this is working correctly, I can check the correct results but I would like to launch this script in another script on the first RPI. So, I put the previous command in the file : script_RPI1.py.
Then, I am launching the script : sudo python script_RPI1.py
And I got the following error :
ssh pi#192.168.x.x
^
SyntaxError: invalid syntax
Anyone has an idea concerning my problem ?
How are you launching the script? What appears from the minimal information you gave is that you are trying or to do that command within the Python interactive interpreter or that you want to execute it in the interpreter and you forgot to surround it with quotes(") in order to make it as a string.
Try to explain a bit more please.
You want to run a bash command:
ssh pi#192.168.x.x 'sudo python script_RPI2.py'
you show do it in a .sh file as in the following example:
#!/bin/sh
ssh pi#192.168.x.x 'sudo python script_RPI2.py'
After saving this file just do ./name_of_file.sh, which will simply run your bash file in the terminal, if you want to run a python script that opens a terminal in another process and executes string that are terminal commands you should look at something like this:
from subprocess import call
call(["ls"])
This will execute ls in another terminal process and return the result back to you. Please check what you want to actually do and decide on one of these paths.
Modified the entire answer and actually put some extra time on the code. The full solution for you to integrate will look something like the code below. Note that the code is setup in a way that you can define the host to connect to, along with the command you want to execute in the remote RPi
import subprocess
import sys
remoteHost="pi#192.168.x.x"
command="python /path/to/script.py"
ssh = subprocess.Popen(["ssh", "%s" % remoteHost, command],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if result == []:
error = ssh.stderr.readlines()
print >>sys.stderr, "ERROR: %s" % error
else:
print result
yourVar = result ### This is where you assign the remote result to a variable

"No such file or directory" error when calling fc-list in python

I am attempting to scrape a terminal window of the list of fonts installed on the curent hosting server. I have written the following code:
import subprocess
cmd = 'fc-list'
output = subprocess.Popen(cmd, stdout=subprocess.PIPE ).communicate()[0]
but when i call this code, an exception is raised:
[Errno 2] No such file or directory
I can open a terminal window, and this works fine. What am i doing wrong?
You need to provide the absolute path to the executable. When you open a terminal window you then have a shell running which will search in $PATH to find the program. When you run the program directly, via subprocess, you do not have a shell to search $PATH. (note: it is possible to tell subprocess that you do want a shell, but usually this leads to security vulnerabilities)
Here is what you would want to use:
import subprocess
cmd = '/usr/local/bin/fc-list'
output = subprocess.Popen(cmd, stdout=subprocess.PIPE ).communicate()[0]

Running a PowerShell cmdlet in a Python script

I have a Python script and I want to run a PowerShell cmdlet. I've looked online and the only thing I can find is running a PowerShell script, but I feel like writing a cmdlet to a script and then dot sourcing it for execution would take a lot longer than needed.
I've tried using subprocess.Popen in the following way:
cmd = subprocess.Popen(['C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe', ps_cmdlet])
But ps_cmdlet is a python string variable with a powershell cmdlet as its value. So, I'm obviously getting a "No such file or directory" error. Is there any way to run a powershell cmdlet in a python script without using things like IronPython?
Thanks!
This works rather well
import subprocess
pl = subprocess.Popen(['powershell', 'get-process'], stdout=subprocess.PIPE).communicate()[0]
print(pl.decode('utf-8'))
Try the following (ps_cmdlet is a python string):
subprocess.call(ps_cmdlet)
edit: Here is an example that will output your machine's ip configuration to Powershell:
ps_cmdlet = 'ipconfig'
subprocess.call(ps_cmdlet)
another edit: Another way that works for me is:
ps_cmdlet = 'whatever command you would enter in powershell'
p = subprocess.Popen(ps_cmdlet,stdout=subprocess.PIPE)
p.communicate()
import subprocess
process = subprocess.Popen([r"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "get-process"],
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
process_output = process.read().splitlines()
Above script would help in executing PS Cmdlets from Python.

Can't get output from Popen when run through IIS

I'm using the following python script on Windows Server 2008:
import cgitb
import subprocess
cgitb.enable()
print "Content-Type: text/plain;charset=utf-8"
print
cmd = "git tag"
process = subprocess.Popen(cmd.split(), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
git_output = process.communicate()[0]
print "git output = %s" % git_output
There are, in fact, some git tags. Running this script through the shell works perfectly. However, when run through IIS (7), the output seems to be empty.
I've tried directing the Popen output to a file instead of PIPE. Again, worked when running from the command line, didn't work when running through IIS.
Any ideas?
EDIT:
Following #Wooble's advice, I removed the [0] from the call to communicate to see git errors, and indeed found the enigmatic error "'git' is not recognized as an internal or external command, operable program or batch file." Of course git is installed on the system, and as I said the script works when run directly through the command line.
To no avail, I tried:
Setting the command to use the full path of the git executable
Adding the full path of the git executable directory to python's sys.path
Copying the actual git executable to the working directory - this removed the "git not recognized" error but still yielded an empty result!
Please help!!
I don't know why the path was partial when running from IIS (explanations welcome!), but adding this finally solved the problem:
git_path = "C:\\Program Files (x86)\\Git\\bin\\"
os.environ["PATH"} += git_path + ';'

Categories