sys.exit(myString) doesn't mean "return this string". If you pass a string to sys.exit, sys.exit will consider that string to be an error message, and it will write that string to stderr. The closest concept to a return value for an entire program is its exit status, which must be an integer.
If you want to capture output written to stderr, you can do something like
python yourscript 2> return_file
You could do something like that in your bash script
output=$((your command here) 2> &1)
This is not guaranteed to capture only the value passed to sys.exit, though. Anything else written to stderr will also be captured, which might include logging output or stack traces.
example:
test.py
print "something"
exit('ohoh')
t.sh
va=$(python test.py 2>&1)
mkdir $va
bash t.sh
edit
Not sure why but in that case, I would write a main script and two other scripts... Mixing python and bash is pointless unless you really need to.
import script1
import script2
if __name__ == '__main__':
filename = script1.run(sys.args)
script2.run(filename)
Answer from Loïc Faure-Lacroix on Stack Overflowsys.exit(myString) doesn't mean "return this string". If you pass a string to sys.exit, sys.exit will consider that string to be an error message, and it will write that string to stderr. The closest concept to a return value for an entire program is its exit status, which must be an integer.
If you want to capture output written to stderr, you can do something like
python yourscript 2> return_file
You could do something like that in your bash script
output=$((your command here) 2> &1)
This is not guaranteed to capture only the value passed to sys.exit, though. Anything else written to stderr will also be captured, which might include logging output or stack traces.
example:
test.py
print "something"
exit('ohoh')
t.sh
va=$(python test.py 2>&1)
mkdir $va
bash t.sh
edit
Not sure why but in that case, I would write a main script and two other scripts... Mixing python and bash is pointless unless you really need to.
import script1
import script2
if __name__ == '__main__':
filename = script1.run(sys.args)
script2.run(filename)
sys.exit() should return an integer, not a string:
sys.exit(1)
The value 1 is in $?.
$ cat e.py
import sys
sys.exit(1)
$ python e.py
$ echo $?
1
Edit:
If you want to write to stderr, use sys.stderr.
linux - return value from python script to shell script - Stack Overflow
redirecting python ouput to bash variables
linux - How to return a value from a shell script in a python script - Stack Overflow
Return value to Python script from Bash script - Stack Overflow
Within sh which is actually dash on Ubuntu the builtin command return can returns only numerical values - exit statuses, which have a meaning in a context of a function or sourced script. Source man sh:
The syntax of the return command is
return [exitstatus]
Everything other with your shell script looks correct. I think you need to use echo $COLOR instead return and suppress other echo-es.
In case you need to return more data to the main script you can output everything as one line and divide the separate fields by some character that will play role of a delimiter in the main script on which base you can convert the string into an array. For example (where , is our delimiter and -n will suppers the newline character within echo):
echo -n "$COLOR","$exitstatus"
The other information that is provided by the script and is not required by the main script could be redirected to some log file:
$ cat whiptail.sh
#!/bin/sh
log_file='/tmp/my.log'
COLOR=$(whiptail --inputbox "What is your favorite Color?" 8 78 Blue --title "Example Dialog" 3>&1 1>&2 2>&3)
exitstatus=
exitstatus = 0 ]; then
echo "User selected Ok and entered $COLOR" > "$log_file"
echo -n "$COLOR","$exitstatus"
else
echo "User selected Cancel." >> "$log_file"
echo -n "CANCEL","$exitstatus"
fi
Unfortunately I don't have much experience with Python, but here is a sample .py script that can handle the output of the above .sh script (reference):
$ cat main-script.py
#!/usr/bin/python
import subprocess
p = subprocess.Popen(['./whiptail.sh'], stdout=subprocess.PIPE)
p = p.communicate()[0]
p = p.split(",")
print "Color: " + p[0]
print "ExitCode: " + p[1]
I had a similar problem where I needed the return value from a shell command in my Python script.
The subprocess method check_output() helped me get the shell return code as a byte string in the Python file.
Here is the code:
return_value =subprocess.check_output("sudo raspi-config nonint get_spi", stderr=subprocess.STDOUT, shell = True)
print(return_value)
<<<b'1\n'
added 2>&1 to the end and it is now working
e.g
serverquery=$(./serverquery.py 127.0.0.1 27015 2>&1)
If you have access to edit serverquery.py, I would change the exit value for the error conditions and then simply check the value of $? after running it. If not, try changing your if conditional on output check to the format suggested by val0x00ff: if [[ "${serverquery}" == "ERROR 1" ]]; then ... fi.
You can't return message as exit code, only numbers. In bash it can accessible via $?. Also you can use sys.argv to access code parameters:
import sys
if sys.argv[1]=='hi':
print 'Salaam'
sys.exit(0)
in shell:
#!/bin/bash
# script for tesing
clear
echo "............script started............"
sleep 1
result=`python python/pythonScript1.py "hi"`
if [ "$result" == "Salaam" ]; then
echo "script return correct response"
fi
Pass command line arguments to shell script to Python like this:
python script.py $1 $2 $3
Print the return code like this:
echo $?
I have a python script that I want to run in a .sh file
the python script contains two print statements one of them is a number and another is a link
i would like to further use them in my bash as two separate variables.
!/bin/sh
outputString=`python3 draft.py`
echo $outputString < -- this prints my number and a link that I want to assign to two variables to further use in my bash.
Any help is welcome
Thanks
EDIT:
I found the set command that seems to split it into variables and can call them with $1 and $2.
Thanks for the help guys.
outputString=$(python3 draft.py)
set $outputString
wget $2
gzip $1.gz -d
Use subprocess.check_output:
import subprocess
answer = subprocess.check_output(['./a.sh'])
print("the answer is {}".format(answer))
help on subprocess.check_output:
>>> print subprocess.check_output.__doc__
Run command with arguments and return its output as a byte string.
Demo:
>>> import subprocess
>>> answer = subprocess.check_output(['./a.sh'])
>>> answer
'Hello World!\n'
>>> print("the answer is {}".format(answer))
the answer is Hello World!
a.sh :
#!/bin/bash
STR="Hello World!"
echo $STR
use Subprocess.check_output instead of Subprocess.call.
Subprocess.call returns return code of that script.
Subprocess.check_output returns byte stream of script output.
Subprocess.check_output on python 3.3 doc site
I would print it to a file chosen on the command line then I'd get that value in bash with something like cat.
So you'd go:
python b.py tempfile.txt
var=`cat tempfile.txt`
rm tempfile.txt
[EDIT, another idea based on other answers]
Your other option is to format your output carefully so you can use bash functions like head/tail to pipe only the first/last lines into your next program.
I believe the answer is
.py
import sys
a=['zero','one','two','three']
b = int(sys.argv[1])
###your python script can still print to stderr if it likes to
print >> sys.stderr, "I am no converting"
result = a[b]
print result
.sh
#!/bin/sh
num=2
text=`python numtotext.py $num`
echo "$num as text is $text"
To get the output of a command in a variable, use process substitution:
var=$( cmd )
eg
var=$( ls $HOME )
or
var=$( python myscript.py)
The $() is (almost) exactly equivalent to using backticks, but the backticks syntax is deprecated and $() is preferred.
If your intent is to return a string 'working' or 'not working' and use that value in the shell script to determine whether or not the python script was successful, change your plan. It is much better to use a return value. eg, in python you 'return 0' or 'return 1' (zero for success, 1 for failure), and then the shell script is simply:
if python call_py.py; then
echo success
else
echo failure
fi
Use $(...) to capture a command's stdout as a string.
output=$(./script.py)
echo "output was '$output'"
if [[ $output == foobar ]]; then
do-something
else
do-something-else
fi
To execute a python script in a bash script you need to call the same command that you would within a terminal. For instance
> python python_script.py var1 var2
To access these variables within python you will need
import sys
print(sys.argv[0]) # prints python_script.py
print(sys.argv[1]) # prints var1
print(sys.argv[2]) # prints var2
Beside sys.argv, also take a look at the argparse module, which helps define options and arguments for scripts.
The argparse module makes it easy to write user-friendly command-line interfaces.