How can I call a python script from a python script - python

I have a python script 'b.py' which prints out time ever 5 sec.
while (1):
print "Start : %s" % time.ctime()
time.sleep( 5 )
print "End : %s" % time.ctime()
time.sleep( 5 )
And in my a.py, I call b.py by:
def run_b():
print "Calling run b"
try:
cmd = ["./b.py"]
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, b''):
print (">>>" + line.rstrip())
except OSError as e:
print >>sys.stderr, "fcs Execution failed:", e
return None
and later on, I kill 'b.py' by:
PS_PATH = "/usr/bin/ps -efW"
def kill_b(program):
try:
cmd = shlex.split(PS_PATH)
retval = subprocess.check_output(cmd).rstrip()
for line in retval.splitlines():
if program in line:
print "line =" + line
pid = line.split(None)[1]
os.kill(int(pid), signal.SIGKILL)
except OSError as e:
print >>sys.stderr, "kill_all Execution failed:", e
except subprocess.CalledProcessError as e:
print >>sys.stderr, "kill_all Execution failed:", e
run_b()
time.sleep(600)
kill_b("b.py")
I have 2 questions.
1. why I don't see any prints out from 'b.py' and when I do 'ps -efW' I don't see a process named 'b.py'?
2. Why when I kill a process like above, I see 'permission declined'?
I am running above script on cygwin under windows.
Thank you.

Why I don't see any prints out from 'b.py' and when I do 'ps -efW' I don't see a process named 'b.py'?
Change run_b() lines:
p = subprocess.Popen(cmd,
stdout=sys.stdout,
stderr=sys.stderr)
You will not see a process named "b.py" but something like "python b.py" which is little different. You should use pid instead of name to find it (in your code "p.pid" has the pid).
Why when I kill a process like above, I see 'permission declined'?
os.kill is supported under Windows only 2.7+ and acts a little bit different than posix version. However you can use "p.pid". Best way to kill a process in a cross platform way is:
if platform.system() == "Windows":
subprocess.Popen("taskkill /F /T /PID %i" % p.pid, shell=True)
else:
os.killpg(p.pid, signal.SIGKILL)
killpg works also on OS X and other Unixy operating systems.

Related

Python - evaluate shell command before executing it

I have a Python function that I made with the subprocess package:
def run_sh(command):
"""Print output of bash command"""
try:
process = Popen(shlex.split(command), stdout=PIPE)
for line in TextIOWrapper(process.stdout, newline=""):
print(line)
except CalledProcessError as e:
raise RuntimeError(
"command '{}' return with error (code {}): {}".format(
e.cmd, e.returncode, e.output
)
)
Let's say I want to run the following from within my Python script:
run_sh(newman run MY_COLLECTION.json "--env-var 'current_branch'=`git branch --show-current`")
Currently, it does not evaluate it as git branch --show-current but just treats it like test - how do I get it to evaluate it from my shell, and then run it?
Thanks!
Here's a code snippet that might help
import subprocess
def run_command(cmd):
try:
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if out:
print(out.decode())
if err:
print(err.decode())
except Exception as e:
print(e)
if __name__ == '__main__':
run_command('ls -l')
run_command('ls -l /tmp')
run_command('ls -l /tmp1')

Python - Trouble getting exception - os.system command

I am getting 'Unknown Error' with the value of 128. Here are the things I have tried and I cannot manage to get into the exception block.
Also in the console I am getting:
ERROR: The process "NULL.exe" not found.
try:
tmp = os.system("c:/windows/system32/taskkill /f /im NULL.exe")
except OSError as e:
print("We made it into the excepetion!!" + str(e))
try:
tmp = os.system("c:/windows/system32/taskkill /f /im NULL.exe")
except OSError:
print("We made it into the excepetion!!")
try:
tmp = os.system("c:/windows/system32/taskkill /f /im NULL.exe")
except os.error:
print("We made it into the excepetion!!")
try:
tmp = os.system("c:/windows/system32/taskkill /f /im NULL.exe")
except ValueError:
print("We made it into the excepetion!!")
try:
tmp = os.system("c:/windows/system32/taskkill /f /im NULL.exe")
except:
print("We made it into the excepetion!!")
os.system() doesn't throw an exception when the command fails (or isn't found). It just throws an exception when you are using the wrong argument type (it demands a string). If you really need an exception you can use subprocess.call().
Python won't no when your command failed its only catches the return code from the command you just have ran.
So you have to make custom expection and raise it based on the return value.
I runned some experiments with your command.
Here is the error codes and there meanings what i found:
0--Task killed succesfully
1--Acces denided
128--Process Not found
My code for your problem:
import os
#Making a custom Expection for ourselfs
class TaskkillError(Exception):
def __init__(self, value): #value is the string we will return when expection is raised
self.value = value
def __str__(self):
return repr(self.value)
tmp = os.system("c:/windows/system32/taskkill /f /im NULL.exe")
if tmp!=0:
if tmp==1:
raise TaskkillError('Acces denided') #Error code=1 Permission Error
if tmp==128:
raise TaskkillError("Process not found") #Error code=128 Process not found
else:
raise TaskkillError("UnknowError Error Code returned by taskkill:"+str(tmp))
else:
print("Task succesfully killed")
Okay guys I figured it out finally, thank you so much for the help. I was trying to use subprocess.run, call, check_output, check_call etc. Also different params for stderr etc. I also tried catching every type of error I read about. Kept throwing errors to the console every time. This wouldn't work in my situation because I am looking for both a 32bit and 64bit process knowing one of them is going to fail every time.
Ultimately all I had to do was use Popen. By using Popen I could basically feed the errors into PIPE and I actually didn't even need a try/except block. Thanks again for all the help, here is a sample code.
from subprocess import Popen, PIPE
bit32 = True
bit64 = True
p = Popen('c:windows/system32/taskkill /f /im notepad.exe', shell=True, stdout=PIPE,
stderr=PIPE)
output,error = p.communicate()
if (len(output) == 0):
print("32 bit not found")
bit32 = False
if (len(output) > 0):
print(output)
p = Popen('c:windows/system32/taskkill /f /im notepad64EXAMPLE.exe', shell=True,
stdout=PIPE, stderr=PIPE)
output,error = p.communicate()
if (len(output) == 0):
print("64 bit not found")
bit64 = False
if (len(output) > 0):
print(output)
if(not bit32 and not bit64):
print("Could not find 32/64 bit process")

PYTHON check for a program if it's up and running

I have a python script that parse some files, but sometimes appear unknown errors and script will fail.
So i tried to make a program that check for a file which have timestamp pid, and main program will update timestamp every 30 seconds.
def start_server():
subprocess.Popen("C:\Server.py", shell=True)
while True:
f = open('C:\server.conf', 'r+')
text = f.read().split(' ')
pid = int(text[0])
lastTime = text[1]
if float(time.time()) - float(lastTime) > 90:
temp = subprocess.Popen("taskkill /F /T /PID %i" % pid , stdout=subprocess.PIPE, shell=True)
out, err = temp.communicate()
print ' [INFO] Server.py was killed, and started again.'
start_server()
time.sleep(30)
but this doesn't start new server.py if last instance of program will fail.
Any ideea how i can make this works?
Thanks!

subprocess.Popen won't execute

In my code I have the following:
...
subp_001 = subprocess.Popen('./my001Script.sh %s %s' % (param1, param2), shell=True, preexec_fn=os.setsid)
#atexit.register(subp_001.terminate)
time.sleep(5)
os.killpg(subp_001.pid, signal.SIGTERM)
...
At some moment, verything was working, that means my001Script runs then the execution of the rest of the python code stops for that 5 seconds the afet rthat the script is killed, then I don't remember exactly what I have changed that made my001Script never runs again, unless I take off time.sleep().
I would like to find a way to execute the script and after some seconds I kill it.
I've also tried to do the following instead:
...
subp_001 = subprocess.Popen('./my001Script.sh %s %s' % (param1, param2), shell=True, preexec_fn=os.setsid)
#atexit.register(subp_001.terminate)
threading.Timer(5,killingBroadcastAck).start()
...
Same thing, my001Script is not executing at all, by the way I realize that if it does not execute I should expect an error at os.killpg(subp_001.pid, signal.SIGTERM). I don't get such error.
Any hints ?
Works for me with these minimal tests. Are you sure your script is really not executing?
This runs the process, which is completed in less than 5 secs, and then gives an error as can't kill the process that wasn't there anymore I think:
p = subprocess.Popen('echo hello', shell=True, preexec_fn=os.setsid)
print "done"
time.sleep(5)
os.killpg(p.pid, signal.SIGTERM)
print "waited"
output:
done
hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 1] Operation not permitted
And then when change the sleep to 0 so it's quick enough to kill the process while it's still there it again works as expected:
p = subprocess.Popen('echo hello', shell=True, preexec_fn=os.setsid)
print "done"
time.sleep(0)
os.killpg(p.pid, signal.SIGTERM)
print "waited"
outputs:
done
waited

Subprocess.poll() falsely returns a value

test1.py:
process = Popen(["python","test2.py"])
time.sleep(3)
alive = process.poll()
if alive is None:
print "Still running"
else:
print "Not running\r\n"
print "%r" % alive
test1.py Output:
Not running
2
test2.py:
time.sleep(30)
print "done"
What is going on? Shouldn't this return "Still running"?
Because of a contradicting result here's the full test1.py code:
import cStringIO
import os
import cgi
import time
from subprocess import Popen
def application(environ, start_response):
headers = []
headers.append(('Content-Type', 'text/plain'))
write = start_response('200 OK', headers)
input = environ['wsgi.input']
output = cStringIO.StringIO()
process = Popen(["python","test2.py"])
time.sleep(3)
alive = process.poll()
if alive is None:
print >> output, "Still running"
else:
print >> output, "Not running\r\n"
print >> output, "%r" % alive
output.write(input.read(int(environ.get('CONTENT_LENGTH', '0'))))
return [output.getvalue()]
Updated test1.py:
process = Popen(["python","C:/wamp/www/python/popen/test2.py"], shell=True)
time.sleep(5)
alive = process.poll()
if alive is None:
#print >> output, "%r" % alive
print >> output, "Still running"
else:
print >> output, "Not running"
print >> output, "%r" % alive
print >> output, "Current working dir : %s" % os.getcwd()
print >> output, os.strerror(0)
Updated Output:
Not running
0
Current working dir : C:\wamp\bin\apache\apache2.2.22
No error
If Popen() cannot find test2.py, it produces the error "No such file or directory", with errno 2. This error number is returned by poll(). Since you seem to be running this script through wsgi, something seems to be gulping your stderr and you don't see the error message:
$ cat test1.py
from subprocess import Popen
import time
process = Popen(["python","doesnotexist.py"])
time.sleep(3)
alive = process.poll()
if alive is None:
print "Still running"
else:
print "Not running\r\n"
print "%r" % alive
$ python test1.py
python: can't open file 'doesnotexist.py': [Errno 2] No such file or directory
Not running
2
Now, the issue is probably because your current working directory of your script is not set to the script's directory by the front end server, try printing os.getcwd() to see if it's what you're expecting.
According to this
An exit status of 2 indicates an issue with the shell executing the command. Have you tried running test2.py directly in the shell to verify there aren't issues with it? As Lie pointed out it could be that the shell can't find the file you're trying to execute, though there could be another issue causing it to break.

Categories