I have a python script in my cgi-bin where I am calling another perl script which in turn calls a python script to perform some tests. It works perfectly fine when I run it from the command line, but throws import error: no module named paramiko when I run from Apache. I have even printed:
import site
sys.path.append('/usr/local/lib/python2.7/site-packages/')
import paramiko
from paramiko import SSHClient
in my python script, but I get an error when I run from browser.
My python code which calls the perl script is as below:
def execute_ACL():
print "Going to execute"
for line in run_command("perl systemtcpcheck.pl acl/config_files/G2AXStageg2ax-stage.hosts acl/config_files/G2AXStageg2ax-live.tests"):
print(line)
def run_command(command):
p = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return p.communicate()
Can anyone please suggest a solution ?
Related
This question already has answers here:
Store output of subprocess.Popen call in a string [duplicate]
(15 answers)
Closed 4 years ago.
I've created and deployed a Flask App with Apache2 server WSGI in which now would like to run a .sh script from the App. However, from calling from python code, it doesn't execute.
Here is the test.sh:
#!/bin/bash
echo "hi from shell script"
Here is my python flask app code index.py (runs when App is opened) but nothing is printed or executed:
import subprocess
subprocess.call('/var/www/FlaskApp/FlaskApp/scripts/test.sh')
To check that there is not errors in my code, I've check flask error logs, and no errors. Also, I created a script called test_shell_script.py with same python code as above (but not flask app code) and it runs great like this:
# test_shell_script.py
import subprocess
subprocess.call('/var/www/FlaskApp/FlaskApp/scripts/test.sh')
And then run it with python:
python3 /var/www/FlaskApp/FlaskApp/test_shell_script.py
hi from shell script
I did change the permissions as well:
-rwxr-xr-x 1 root root 364 Nov 19 17:48 ../scripts/test.sh
What am I missing here which is not allowing my Flask app to run shell commands from the python code?
To show command output inside Python, there are two popular methods:
check_output(): It runs command with arguments and return its output. (official documentation)
subprocess.communicate(): Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. (official documentation)
I could view the shell file output using both methods using Python 3.5 in an Ubuntu machine.
app.py:
import subprocess
from subprocess import Popen, PIPE
from subprocess import check_output
from flask import Flask
def get_shell_script_output_using_communicate():
session = Popen(['./some.sh'], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()
if stderr:
raise Exception("Error "+str(stderr))
return stdout.decode('utf-8')
def get_shell_script_output_using_check_output():
stdout = check_output(['./some.sh']).decode('utf-8')
return stdout
app = Flask(__name__)
#app.route('/',methods=['GET',])
def home():
return '<pre>'+get_shell_script_output_using_check_output()+'</pre>'
app.run(debug=True)
some.sh:
#!/bin/bash
echo "hi from shell script"
echo "hello from shell script"
Output screenshot:
I would like to connect a remote machine and run background script in that machine from python.
I tried:
os.system("ssh root#10.0.0.1 \' nohup script.sh & \')
But it seems not working. And if I put nohup in script.sh, and simply run
os.system("ssh root#10.0.0.1 \' script.sh \'")
The nohup command would not work in either cases.
I'm confused why so, and is there anybody knows how to do background job from python or it's just impossible doing it this way?
What kind of errors are you getting? What version of Python are you using?
You should take a look at this Python subprocess - run multiple shell commands over SSH
import subprocess
sshProcess = subprocess.Popen(["ssh", "root#10.0.0.1"],
stdin=subprocess.PIPE,
stdout = subprocess.PIPE,
universal_newlines=True,
bufsize=0)
sshProcess.stdin.write("nohup script.sh &")
For example you have a local script (python, bash, etc. Here I am demonstrating you using a python script)
First you create a python file locally. Lets say hello.py
# 'hello.py'
import os
print os.system('hostname')
Secondly now a python script which would execute the above hello.py on a remote machine
import pathos
copy = pathos.core.copy('hello.py', destination='abc.remote.com:~/hello.py')
exec = pathos.core.execute('python hello.py', host='.remote.com')
print exec.response()
I am new to windows python. I am trying to run a command line tool using python. This tool will flash the firmware connecting to IP address of the machine. I could open cmd prompt and use the command
C:\ToolsSuite>sdi --ip 172.23.240.41 --fwdl "c:\BUILDS\firmware_image.zip
.This works for me very well.
But when I try to execute using the python script on windows, I am not able to do that. Python script looks like this.
import subprocess
import os
os.chdir(r"C:\ToolsSuite")
#os.system('cd c:\mydir')
os.system("sdi --ip 192.92.48.32 --fwdl C:\firmware_image.zip")
#subprocess.Popen(r'sdi --ip 192.92.48.32 --fwdl "c:\firmware_image.zip"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
The exception thrown is "Could not find file". I am not getting how to give the path of the firmware file when it is stored in some location, say for example 'C' drive or in some folder location of windows.
If the sdi executable is in "C:\ToolsSuite", this should work:
subprocess.call(['sdi', '--ip 192.92.48.32', r'--fwdl "c:\firmware_image.zip"'])
If you want to call a Windows command, you need to give the full path to the command.
You can try:
import subprocess
import os.path
# C:\ToolsSuite>sdi --ip 172.23.240.41 --fwdl "c:\BUILDS\firmware_image.zip"
cmd = os.path.join("C:\\ToolsSuite", "sdi")
args = [cmd,
'--ip', '172.23.240.41',
'--fwdl', 'c:\\BUILDS\\firmware_image.zip']
subprocess.check_call(args)
Here, check_call is useful to replace non-zero exit code by an exception. Of course, you can also choose another function of the same family.
Hi I am trying to create a script using python to log on to a server and to check the status of the cluster by running a clustat command. When I do this I get the following error:
/bin/sh: clustat: command not found
As I understand it, it's not able to run the command as this is a non standard bash command that is being used. I was hoping someone would have some ideas to get around this to get it work.
Below is the method used to run the command:(I have antoher method to ssh onto the system it works fine)
def run_cmd(command):
"""Function for running command on the system."""
proc = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
return out
This is where it seems to go wrong. I know the run_cmd method works as I am able to use it with other commands:
run_cmd("clustat >> out.txt")
return ""
subprocess runs the commands locally.
You will have to use paramiko.SSHClient to run commands on the remote machine.
ssh_client = paramiko.SSHClient()
ssh_client.connect(host='some_host', username='username', password='password')
ssh_client.exec_command('clustat >> out.txt')
I am trying to write a python script that benchmarks several pieces of code. The issue is when the script is run the output of the command id different from what I would get it I run it directly at bash prompt.
Here is the code for the python script
import subprocess
import re
import os
app = os.getcwd() + "/" + "myapp"
testPopen = subprocess.Popen(args=['/usr/bin/time',app],
stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=False)
testPopen.wait()
Here is the ouput of above code
real 1.0
user 0.8
sys 0.0
When you run time myapp from the bash prompt, you are using bash's time command. (Type help time to see that bash understands it as a bash command.)
When you run the python script you are using /usr/bin/time, which is a different program. (Type man time or which time to see that time is also a program. How confusing!)
To get the python script to use the bash time command:
import shlex
testPopen = subprocess.Popen(shlex.split('bash -c "time {a}"'.format(a = app)),
stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=False)
out,err = testPopen.communicate()
print(err)