subprocess output data word recognition - python

may be this question was asked already but i cant find answer what works for me so please need your help . I try write script what automaticly will start another script if service down, in my case apache2 , i write small script but i cant make it work its not recognize output , please your help , here the script :
import os
import subprocess
service = "apache2"
p = subprocess.Popen(["systemctl", "is-active", service], stdout=subprocess.PIPE)
(output, err) = p.communicate()
output = output.decode('utf-8')
print 'APA Serv :',(output)
if output == "inactive":
print '\x1b[31;1m' + ' Attention!' + '\x1b[0m'
os.system('sudo python baz.py')
time.sleep(2)
p.stdout.close()

Related

Understanding subprocess module in python when running program from python script

I usually run a program from my OpenSuse linux terminal by typing ./run file_name. This will bring up a series of options that I can choose from by typing a numeric value 0-9 and hitting return on my keyboard. Now I want to do this from a python script automatically. My example below is not working, but I can't understand where I'm failing and how to debug:
import subprocess
p = subprocess.Popen(["/path/to/program/run", file_name], stdin = subprocess.PIPE,stdout=subprocess.PIPE,shell=False)
print "Hello"
out, err = p.communicate(input='0\r\n')
print out
print err
for line in p.stdout.readlines():
print line
The output of this program is just
>> Hello
>>
i.e. then it seems to freeze (I have no idea whats actually happening!) I would have expected to see what I see when I run ./run file_name
and hit 0 and then return directly in my terminal, but I assure you this is not the case.
What can I do to debug my code?
Edit 1: as suggested in comments
import subprocess
fileName = 'test_profile'
p = subprocess.Popen(["/path/to/program/run", fileName], stdin = subprocess.PIPE,stdout=subprocess.PIPE,shell=False)
print "Hello"
for line in iter(p.stdout.readline,""):
print line
will indeed return the stdout of my program!
communicate waits for the completion of the program. For example:
import subprocess
p = subprocess.Popen(["cut", "-c2"], stdin=subprocess.PIPE, stdout=subprocess.PIPE,shell=False)
out, err = p.communicate(input='abc')
print("Result: '{}'".format(out.strip()))
# Result: 'b'
It sounds like you have a more interactive script, in which case you probably should try out pexpect
import pexpect
child = pexpect.spawn('cut -c2')
child.sendline('abc')
child.readline() # repeat what was typed
print(child.readline()) # prints 'b'

Returning gracefully from Matlab back to python

I call Matlab code from python as
matlab_cmd_string = MatlabExePth+ " -nosplash -nodesktop -wait -logfile FileIoReg_MatlabRemoteRun.log -minimize -r "
fname = 'CompareMse '
mat_cmd = matlab_cmd_string + fname + ", exit\""
which gets translated as
'C:\Program Files\MATLAB\R2013b\bin\matlab.exe -nosplash -nodesktop
-wait -logfile FileIoReg_MatlabRemoteRun.log -minimize -r CompareMse , exit'
The Matlab code does its job and then prints error and stops execution using following construct:
if(mse> thr)
error('mse has increased');
end
However, the control is not given back to python.
I tried following commands in python:
msg=subprocess.check_output(mat_cmd,stderr=subprocess.STDOUT,shell=False)
msg comes empty and console window dosn't show up anything as control is not got back. Same with following method :
proc = subprocess.Popen(mat_cmd , stdout=subprocess.PIPE, shell=True)
out, err = proc.communicate()
output = out.upper()
proc.returncode
If I write following in matlab,
if(mse> thr)
warning('mse has increased');
return
end
I get control back to python with following:
msg=subprocess.check_output(mat_cmd,stderr=subprocess.STDOUT,shell=False)
proc = subprocess.Popen(mat_cmd , stdout=subprocess.PIPE, shell=True)
out, err = proc.communicate()
output = out.upper()
proc.returncode
msg,out show as "" , err is NONE , and proc.returncode is 0
What is need is functionality in Matlab:
for i=1:3
% Some code here
if(mse> thr)
[print error,return user defined exit code and error message back to python variable]
if (mse_new >mse_old)
[print warning,do not return, but capture warning back to
Python variable]
% some code here
the difficulty with warning is that if the condition for warning happens in loop iteration 1, and not for 2nd and third time, Python should be able to understand that Matlab code had not errors but one warning and should capture that.( and matlab should not exit at iteration 1 of for loop but complete all iterations)
any ideas ?
sedy
Try to use subprocess.check_output(*popenargs, **kwargs). You can capture the output of any given command. Check the Python 2.7 subprocess doc in here
import subprocess
msg = subprocess.check_output([MatlabExePth, "-nosplash", "-wait", "-logfile", "FileIoReg_MatlabRemoteRun.log", "-minimize", "-r", fname, ", exit"])
print msg

Python - A way to make interactive a script execution in console

I'm working on a web interface for the Django migrate/makemigrations commands. I've been checking the code, an they use the Python input() to get the answers of the questions.
At the moment I have tried to use the Python subprocess library in order to answer by an external script (a Python script running a Python script).
I have generated a simple script that could be useful as a test:
sum.py
first_number = input("Welcome to the program that sum two numbers, \
please give me the first number: ")
second_number = input("Now, please give me the second number: ")
print("Congratulations, the result of the sum of %s and %s is: %s" %
(first_number, second_number, (first_number + second_number)))
And the only way that I've found to make the script runs the first script:
from subprocess import Popen, PIPE
command = ["python", "sum.py"]
p = Popen(command, stdin=PIPE, stdout=PIPE)
p.stdin.write("1\n")
p.stdin.write("2\n")
print p.communicate()[0]
I've found in internet some days ago some code to make a ping an receive like real time the stdout:
from subprocess import Popen, PIPE
command = ["ping", "192.168.1.137"]
p = Popen(command, stdout=PIPE, stdin=PIPE, )
while p.poll() is None:
print p.stdout.readline()
I've modified the code and tried to run the script:
64 bytes from 192.168.1.137: icmp_seq=7 ttl=64 time=1.655 ms
from subprocess import Popen, PIPE
command = ["python", "suma.py"]
p = Popen(command, stdout=PIPE, stdin=PIPE, )
response = "1\n"
while p.poll() is None:
print p.stdout.readline() #Obtain the message
p.stdin.write(response) #Answer the question
I've found some possibles ways with websockets and node.js like tty.js or web-console, but it could be hard of mantain since I have no much idea of the programming language.
What I find is to receive and send to an HTML page the message from stdout and get the response from the user.
I'm a bit lost, any suggestions will be appreciated.
Thanks.

How do I open a file in python and insert one or more inputs to it?

I've been trying to code a bit of a "game" to help others learn python, but I've run into a wall right after I jumped out of the brainstorming phase.
See, it involves making a script open another script, and then insert input to it. For example:
username = raw_input('Insert username:')
password = raw_input('Insert password:')
if username == user:
if password == 1234:
print('Congratulations, you cracked it!')
This would be my source code. Then I'd have another code, in which I'd write something to open the former script, insert "user" as if I'd typed it myself in the command prompt, and then tried to insert every number between 0 and, say, 10000. So something like:
for n in range(0, 10000)
[Insert script to open file]
[input 'user']
[input n]
How would I go on about to code the last part?
The subprocess module lets you run another program—including a script—and control its input and output. For example:
import subprocess, sys
p = subprocess.Popen([sys.executable, 'thescript.py'], stdin=subprocess.PIPE)
p.stdin.write('user\n')
p.stdin.write('{}\n'.format(n))
p.wait()
If you can build all the input at once and pass it as a single string, you can use communicate.
If you also want to capture its output, add another PIPE for stdout.
import subprocess
p = subprocess.Popen(['python', 'thescript.py'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = p.communicate('user\n{}\n'.format(n))
For details on how this works, read the documentation; it's all explained pretty well. (However, it's not organized perfectly; you might want to read the opening section, then skip down to "Replacing Older Functions", then read the "Frequently Used Arguments", then come back to the top and go through in order.)
If you need to interact with it in any way more complicated than "send all my input, then get all the output", that gets very hard to do correctly, so you should take a look at the third-party pexpect module.
Would this be what you wanted?
import subprocess
for n in range(0, 10000):
p = subprocess.Popen("python another_script.py", shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.write("user\n" + str(n) + "\n")
out = p.stdout.read()
if "cracked" in out:
print "cracked: " + str(n)
break
Okay, I did it. Thanks for the help guys, but I settled with using modules.
I made my own small module like this:
Filename: pass1
def insertpassword(username, password):
if username == 'user':
if password == '12345':
print('You did it!')
Then what I do is:
import pass1
pass1.insertpassword(raw_input('Insert username:'),raw_input('Insert password:'))
As for the cracking:
import pass1
for n in range(0, 100000):
pass1.insertpassword('user', str(n))
Thanks anyway, everyone.

Raspberry Pi: terminate raspistill command from python

I'm trying to use a PHP file on a server to transmit some variables into a Python script which will in turn start a raspistill timelapse on my Raspberry Pi.
I've so far managed to start taking pictures but I'd now like to have a button to kill the timelapse - i've tried many methods including .kill() and .terminate() but cant get it working.
Here is my current python code:
import sys, os, time, datetime
import subprocess
import signal
from time import sleep
tlfreq = int(sys.argv[1])
tltime = int(sys.argv[2])
dir = '/var/www/timelapse/' + sys.argv[3]
if not os.path.exists(dir):
os.makedirs(dir)
cmd = ('raspistill -t ' + str(tltime) + " -tl " + str(tlfreq) + " -o " + dir + "/photo_%04d.jpg")
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
print "Pictures are now being taken every" , tlfreq/1000 , "second/s for a total of", tltime/3600000 , "hours. These are being stored in", dir
Perhaps I need an "if variable = 1 then kill" command and then send the variable to python.
Any help would be greatly appreciated!
Many thanks,
Dan
You can create new python script kill_raspystill.py with this code
import os
os.system("pkill raspistill")
and call that script when you press a button.
I would suggest the signal library: http://docs.python.org/2/library/signal.html

Categories