Capture return value from python - python

I have a shell script TestNode.sh. This script has content like this:
port_up=$(python TestPorts.py)
python TestRPMs.py
Now, I want to capture the value returned by these scripts.
TestPorts.py
def CheckPorts():
if PortWorking(8080):
print "8080 working"
return "8080"
elif PortWorking(9090):
print "9090 working"
return "9090"
But as I checked the answers available, they are not working for me. The print is pushing the value in variable port_up, but I wanted that print should print on the console and the variable port_up should get the value from return statement. Is there a way to achieve this?
Note: I don't wish to use sys.exit(). Is it possible to achieve the same without this?

but I wanted that print should print on the console and the variable port_up should get the value from return statement.
Then don't capture the output. Instead do:
python TestPorts.py
port_up=$? # return value of the last statement
python TestRPMs.py
You could do:
def CheckPorts():
if PortWorking(8080):
sys.stderr.write("8080 working")
print 8080
But then I am not very happy to print "output" to stderr either.
Alternatively, you could skip printing that "8080 working" message in python script and print it from the shell script.
def CheckPorts():
if PortWorking(8080):
return "8080"
and:
port_up=$(python TestPorts.py)
echo "$port_up working"
python TestRPMs.py

To return an exit code from a Python script you can use sys.exit(); exit() may also work. In the Bash (and similar) shell, the exit code of the previous command can be found in $?.
However, the Linux shell exit codes are 8 bit unsigned integers, i.e. in the range 0-255, as mentioned in this answer. So your strategy isn't going to work.
Perhaps you can print "8080 working" to stderr or a logfile and print "8080" to stdout so you can capture it with $().

Related

Powershell executing python: redirect print statements only?

Is there a way in Powershell to redirect the print statements from python one place and the return statements to another place?
For instance i'm trying
$ python myPythonScript.py args >> logFile
I get print statement output in my log file (though it looks awful, cleaning will be the next job)
However, i do not get the return statement values from the python in the output. Nor do i catch them if I use *>>
Any ideas what's happening?
Python Example:
def main(args)
print "This goes to file"
#parse flags...
#do something here...
MyVar = "Please " + "Work"
return MyVar #doesn't go anywhere
if(__name__ == '__main__':
main(sys.argv)
The return value of a program (or exit code) can only be an integer, not a string.
First, ensure you return an int, or do exit(n) where n is an int.
You might want to also fix:
if(__name__ == '__main__'):
return main(sys.argv)
You can then access the return value of your program (script) in Powershell with echo %errorlevel%
If you really want a string to be used by powershell, you should:
print your logs on stderr instead of stdout
print the filename on stdout at end of execution
redirects stderr to your logfile and stdout to a powershell pipe | if you want a redirection - or you can execute the python script within parentheses $() so the result can be used on command line

Python run command and capture result - do not print result to screen

I'm trying to run a command from a python script, but I want to store the output the command produces and then check it for a substring, however it seems it is not being stored in my variable because it still prints to the screen.
So far I have this...
myfile = 'filename.txt'
result = subprocess.Popen(['myprogram.exe', '-f' + myfile], stdout=subprocess.PIPE).communicate()[0]
if result.find("error executing") != -1:
print "error!"
else:
print "success!"
I'm rather new to Python. Can anyone shed some light on WHY when I run this script, the myprogram.exe DOES execute, but it's output is still sent to the screen. If I print the result variable, it DOES have additional output from myprogram.exe, but I need the lines that show the error too.
You're only redirecting stdout. Looks like your program outputs errors to stderr (as expected), add stderr=subprocess.PIPE to the Popen call.

Conditional statement for exit code 0 in Python

Is there a way to have Python print a statement when a script finishes successfully?
Example code would be something like:
if 'code variable' == 0:
print "Script ran successfully"
else:
print "There was an error"
How could I pass the value of the exit code to a variable (e.g. 'code variable')?
I feel like this would be a nice thing to include in a script for other users.
Thanks.
You can do this from the shell -- e.g. in Bash:
python python_code.py && echo "script exited successfully" || echo "there was an error."
You can't have a program write something like this for itself because it doesn't know it's exit code until it has exited -- at which time it isn't running any longer to report the error :-).
There are other things you can do to proxy this behavior from within the process itself:
try:
main()
except SystemExit as ext:
if ext.code:
print ("Error")
else:
print ("Success")
raise SystemExit(ext.code)
else:
print ("Success")
However, this doesn't help if somebody uses os._exit -- and we're only catching sys.exit here, no other exceptions that could be causing a non-zero exit status.
Just write print at the end of a script if it's in form of executing straight from top to bottom. If there's an error, python stops the script and your print won't be executed. The different case is when you use try for managing exceptions.
Or make yourself a script for running python script.py with try and your except will give you an exception for example to a file or wherever you'd like it to store/show.

getting python script to print to terminal without returning as part of stdout

I'm trying to write a python script that returns a value which I can then pass in to a bash script. Thing is that I want a singe value returned in bash, but I want a few things printed to the terminal along the way.
Here is an example script. Let's call it return5.py:
#! /usr/bin/env python
print "hi"
sys.stdout.write(str(5))
what I want is to have this perform this way when I run it from the command line:
~:five=`./return5.py`
hi
~:echo $five
5
but what I get is:
~:five=`./return5.py`
~:echo $five
hi 5
In other words I don't know how to have a python script print and clear the stdout, then assign it to the specific value I want.
Not sure why #yorodm suggests not to use stderr. That's the best option I can think of in this case.
Notice that print will add a newline automatically, but when you use sys.stderr.write, you need to include one yourself with a "\n".
#! /usr/bin/env python
import sys
sys.stderr.write("This is an important message,")
sys.stderr.write(" but I dont want it to be considered")
sys.stderr.write(" part of the output. \n")
sys.stderr.write("It will be printed to the screen.\n")
# The following will be output.
print 5
Using this script looks like this:
bash$ five=`./return5.py`
This is an important message, but I dont want it to be considered part of the output.
It will be printed to the screen.
bash$ echo $five
5
This works because the terminal is really showing you three streams of information : stdout, stdin and stderr. The `cmd` syntax says "capture the stdout from this process", but it doesn't affect what happens to stderr. This was designed exactly for the purpose you're using it for -- communicating information about errors, warnings or what's going on inside the process.
You may not have realized that stdin is also displayed in the terminal, because it's just what shows up when you type. But it wouldn't have to be that way. You could imagine typing into the terminal and having nothing show up. In fact, this is exactly what happens when you type in a password. You're still sending data to stdin, but the terminal is not displaying it.
from my comment..
#!/usr/bin/env python
#foo.py
import sys
print "hi"
sys.exit(5)
then the output
[~] ./foo.py
hi
[~] FIVE=$?
[~] echo $FIVE
5
You can use stdout to output your messages and stderr to capture the values in bash. Unfortunately this is some weird behaviour as stderr is intended for programs to communicate error messages so I strongly advice you against it.
OTOH you can always process your script output in bash

What is the return value of subprocess.call()?

I am not sure what the return value of subprocess.call() means.
Can I safely assume a zero value will always mean that the command executed successfully?
Is the return value equivalent to the exit staus of a shell command?
For example, will the following piece of code work for virtually any command on Linux?
cmd = "foo.txt > bar.txt"
ret = subprocess.call(cmd, shell=True)
if ret != 0:
if ret < 0:
print "Killed by signal", -ret
else:
print "Command failed with return code", ret
else:
print "SUCCESS!!"
Please enlighten me :-)
Yes, Subprocess.call returns "actual process return code".
You can check official documentation of Subprocess.call and Subprocess.Popen.returncode
It is the return code, but keep in mind it's up to the author of the subprocess what the return code means. There is a strong culture of 0 meaning success, but there's nothing enforcing it.
You are at the mercy of the commands that you call.
Consider this:
test.py
#!/usr/bin/env python
success=False
if not success:
exit()
Then running your code (with cmd='test.py') will result in
SUCCESS!!
merely because test.py does not conform to the convention of returning a non-zero value when it is not successful.

Categories

Resources