Return string from Python to Shell script - python

I have Python code like:
x = sys.argv[1]
y = sys.argv[2]
i = sofe_def(x,y)
if i == 0:
print "ERROR"
elif i == 1:
return str(some_var1)
else:
print "OOOps"
num = input("Chose beetwen {0} and {1}".format(some_var2, some_var3))
return str(num)
After I must execute this script in shell script and return string in shell variable, like:
VAR1="foo"
VAR2="bar"
RES=$(python test.py $VAR1 $VAR2)
Unfortunately it doesn't work. The way by stderr, stdout and stdin also doesn't work due to a lot of print and input() in code. So how I can resolve my issue? Thank you for answer

That isn't even valid Python code; you are using return outside of a function. You don't wan't return here, just a print statement.
x, y = sys.argv[1:3]
i = sofe_def(x,y)
if i == 0:
print >>sys.stderr, "ERROR"
elif i == 1:
print str(some_var1)
else:
print >>sys.stderr, "OOOps"
print >>sys.stderr, "Choose between {0} and {1}".format(some_var2, some_var3)
num = raw_input()
print num
(Note some other changes:
Write your error messages to standard error, to avoid them being captured as well.
Use raw_input, not input, in Python 2.
)
Then your shell
VAR1="foo"
VAR2="bar"
RES=$(python test.py "$VAR1" "$VAR2")
should work. Unless you have a good reason not to, always quote parameter expansions.

Just use print instead of return - you bash snippet expects result on STDOUT.

Related

How to get exit code from Python?

I have a python code. I use cmd file to execute my python code. In the cmd file, I am going to get errorlevel from my python code.
infile = "FeatureByte.txt"
Array = ["6J", "yB", "ss", "11"]
with open(infile, "r") as input_file:
output_list = []
for rec in input_file.read().splitlines():
rec = rec[:-3]
FBlist = [rec[i:i+2] for i in range(0, len(rec), 2)]
output_list.append(FBlist)
print(output_list)
FBlist_set = set(FBlist)
Array_set = set (Array)
if Array_set & FBlist_set:
print ("Found")
exit(0)
else:
print ("Not Found")
exit(1)
This is my cmd file :
set logfile=C:\Users\Log.txt
set PYTHONPATH="C:\Users\AppData\Local\Programs\Python\Python37-32"
set PYTHONEXE="%PYTHONPATH%\Python -B"
"C:\Users\AppData\Local\Programs\Python\Python37-32\python.exe" -B C:\Users\Desktop\Pyth.py
echo %ERRORLEVEL% >> "%logfile%"
From these both code, I always get 1 inside my Log.txt file.
I think the problem is in this line:
if Array_set & FBlist_set:
print ("Found")
exit(0)
Change it to:
if Array_set and FBlist_set:
print ("Found")
exit(0)
else:
print ("Not Found")
exit(1)
& that you use is bitwise operator and not the logical operator and. Because of which the if condition fails and you get to the else part which returns exit(1) to you as status code.
The noticed return of 0 and 1 as commented response to roganjosh and Devanshu Misra's solution is because your If-statement is written to do so due to a indentation typo (perhaps lacking an IDE editor?).
You have:
if Array_set & FBlist_set:
print ("Found")
exit(0)
else:
print ("Not Found")
exit(1)
This code always exits with "1". In some cases it exits first with "0" but followed with "1".
It should be:
if Array_set and FBlist_set:
print ("Found")
exit(0)
else:
print ("Not Found")
exit(1) # <--- this exit(1) should be inside the "else" clause.
No need here to point out the use of "&" instead of "and" as this was addressed earlier by roganjosh. Anyway, keep an eye on the changed color of "and". Its blue and means that it became a selection participant in the if-statement.
... but watch out for the result FBlist = [''] because it will trigger a false positive FBlist_set and thus exit the wrong way.
Enjoy ;-)

Python switching the display based on input using If, Else

I want to display print text based on my Input value using IF/Else or Switch. And Also let me know how to use switch case for below code.
# OnButtonOK after clicking it, display the input value
def OnButtonOK(self):
Input = self.entrytext.get()
# self.text.insert(END, Input + '\n')
# self.scroll.config(Input = self.text.yview)
print Input
useroption = atoi(Input)
# self.OnButtonClick();
if (useroption == 1):
print "input is output"
self.SubMenu1();
else:
print "Error:Invalid"
return;
def SubMenu1(self):
print 'SubMenu1'
return;
def SubMenu2(self):
print 'SubMenu2'
return;
def SubMenu3(self):
print 'SubMenu3'
return;
I am able to print only else part:
if (useroption == 1):
print "input is output"
self.SubMenu1();
else:
print "Error:Invalid"
Let me know where exactly i am going wrong.
I think you have indentation problems in your code:
Python use 4 spaces(you can use 1 space but 4 is good practice) indentation language. Means if/else statement will be like this:
if a == 1:
print("A = 1") # 4 spaces w.r.t to above statement
elif a == 2:
print("A = 2")
elif a ==3:
print("A = 4")
else:
print("A = pta nahi")
you can use above if/else statements as a switch case and also your indentation problem will be solved
It's a simple beginner's mistake, you're indenting it worng:
if (useroption == 1):
print "input is output"
self.SubMenu1();
else:
print "Error:Invalid"
should be
if (useroption == 1):
print "input is output" # You had an indent too many here
self.SubMenu1();
else:
print "Error:Invalid"
Python is indentation sensitive; too many or too few indentations will break your code.

I would like to make a program with which you can write other programs

I am having a problem execing the combined strings for the code, it returns the error: unqualified exec in function 'python' it is a nested function
Also sometimes, it does not return an error, but instead results in no output whatsoever.
def python():
prompt=">>> "
lines=0
fullcode=""
enter="\n"
print "\nPython 2.7.8"
print "\nEnter your lines of code, when you are finished enter 'end'."
for x in range(1,1000):
code=raw_input(prompt)
if "end" not in code.lower():
globals()['line%s' % x] = code
lines+=1
else:
break
for x in range(1,lines):
y=x+1
fullcode+=globals() ['line%s' %x] + enter
try:
exec fullcode
except:
print "Error"
python()
Why are you directly manipulating the globals() dict like that?
Anyway, you need to provide exec a context to work in. The full form is
exec fullcode in globals(), locals()
but in your code you shouldn't specify locals() unless you want to give the user access to the local variables defined in your python function.
Also, your conversion loop ends too early, it should be
for x in range(1, lines + 1):
Here's an edited version of your code that should do what you want:
#! /usr/bin/env python
def python():
prompt=">>> "
lines=0
fullcode=""
enter="\n"
print "\nPython 2.7.8"
print "\nEnter your lines of code, when you are finished enter 'end'."
for x in range(1,1000):
code=raw_input(prompt)
if "end" not in code.lower():
globals()['line%s' % x] = code
lines+=1
else:
break
for x in range(1,lines+1):
fullcode+=globals()['line%s' %x] + enter
try:
exec fullcode in globals() #, locals()
except Exception, e:
print "Error:", e
python()
And here's an alternate version of your code that doesn't store each line as a new variable in globals()
#! /usr/bin/env python
import readline
def python():
prompt = ">>> "
codelines = []
print "\nPython 2.7.8"
print "\nEnter your lines of code, when you are finished enter 'end'."
while True:
code = raw_input(prompt)
if "end" not in code.lower():
codelines.append(code)
else:
break
fullcode = '\n'.join(codelines)
#print `fullcode`
try:
exec fullcode #in globals(), locals()
except Exception, e:
print "Error:", e
python()
The import readline statement gives you line editing; but IIRC it doesn't work in Windows.

How to pass when variable = null in python 3

so far I have this:
import datetime
f = open("log.txt", "a", encoding='UTF-8')
print ("Log file created")
print ("Enter /close to leave.")
spc = " "
while 1:
msg = input(">>:")
now = datetime.datetime.now()
now1 = str(now)
if msg == None:
pass
if msg == " ":
pass
else:
msg2 = now1+spc+msg+"\n"
if msg == "/close":
exit()
f.write(msg2)
f.flush()
However, this line is not functioning as I want it, it still returns a blank line on the log file:
if msg == None:
pass
I want it to not return anything and simply continue the while loop, How would I fix this?
You should be using
if msg is None:
pass
Edit
You're missing what the pass function is all about. I would re-write your look like so. This way we're only processing this if the msg is not one of the bad input. Once we're done we break out of the loop.
...
while 1:
msg = input(">>:")
now = datetime.datetime.now()
now1 = str(now)
if not msg in [None, " "]
msg2 = now1+spc+msg+"\n"
if msg == "/close":
exit()
f.write(msg2)
f.flush()
break
Evaluation of the rest of the loop will still continue after pass, and as None does not equal " ", this means the block beginning with msg2 = now1+spc+msg+"\n" will be executed. You need to either unite the if ... if ... else into a single if block by changing if msg == " ": to elif msg == " ": or else change if msg == None: pass to if msg == None: continue.
try:
msg2 = now1+spc+msg+"\n"
if msg == "/close":
exit()
f.write(msg2)
f.flush()
except:
pass #example for a function: return None or raise
Your condition doesn't make any sense. The input function will never return None, only strings.
If you want to skip empty strings, a better test would be if not msg (empty strings are "falsy"). Or, if you want to reject any all-whitespace strings, try if not msg.strip() (which removes leading and trailing whitespace before checking if the rest of the string is empty or not).
Further, it's rarely a good idea to write an if statement that just contains pass. Instead, invert the test so that the condition is true for cases where you want to run some code (in this case, when msg is not empty or all whitespace) and simply omit the cases where you'd do nothing:
while 1:
msg = input(">>:")
now = datetime.datetime.now()
now1 = str(now)
if msg.strip(): # msg is not empty or all whitespace
msg2 = now1+spc+msg+"\n"
if msg == "/close":
exit()
f.write(msg2)
f.flush()
One final issue (unrelated to the main question). Python's exit function is primarily intended for use in the interactive interpreter. It is added to the builtins by the site module, and so it won't exist if Python was run with the -S flag. If you want to close the interpreter, you should instead call sys.exit, raise a SystemExit exception, or just run off the end of the main module (a break statement would probably do that for the loop you've shown here, or perhaps a return if you're in a function somewhere).

Python Regex Syntax

I have the following function:
def handleRequest(self, command, ident, ip, duration=0):
if not re.match("^[0-9]+$", ident) or not re.match("^[0-9.]+$", ip) or \
(duration and not re.match("^[0-9]+$", duration)):
print ("Unknown command")
return
if command == "DOTHIS":
reactor.callInThread(self.func, ident, "./DOTHIS.sh", ip, 0, command)
elif command == "DOTHAT":
reactor.callInThread(self.func, ident, "./DOTHAT.sh", ip, 0, command)
elif command == "DOTHAT":
reactor.callInThread(self.func, ident, "./DOTHING.sh", ip, duration, command)
elif command == "DOMORETHINGS":
reactor.callInThread(self.func, ident, "./DOMORETHINGS.sh", ip, duration, command)
else:
print ("Unknown command")
return
I use this function to execute certain scripts on my server.
My problem is the correct syntaxis of the to be executed commands (DOTHIS, DOTHAT etc.)
It must have something to do with regex.
The commands can have several parameters (e.g. DOTHIS 127.0.0.1).
No matter how I query the command, the result is always "Unknown Command".
Could anyone give me an example of a command with the right syntaxis (including a couple of parameters).
Thanks!
in handleRequest what are you sample inputs ?
i.e for command, ident?
assuming ip='127.0.0.1', duration ='10'
FYI, This condition always make the output False if the string contains just number.
(duration and not re.match("^[0-9]+$", duration))
This assumes all arguments are strings, but this should work:
import re
def handleRequest(self, command, ident, ip, duration=0):
returnEarly = 0
if not re.match("^\d+$", ident):
print ("Invalid ident")
returnEarly = 1
if not re.match("^[\d.]+$", ip):
print ("Invalid ip")
returnEarly = 1
if (duration and not re.match("^\d+$", duration)):
print ("Invalid Duration")
returnEarly = 1
if returnEarly:
return
if command == "DOTHIS":
print ("DOTHIS")
elif command == "DOTHAT":
print ("DOTHAT")
elif command == "DOTHING":
print ("DOTHING")
elif command == "DOMORETHINGS":
print ("DOMORETHING")
else:
print ("Unknown command")
handleRequest("", "DOTHIS", "11", "127.0.0.1", "10") # works
handleRequest("", "BADCOMMAND", "11", "127.0.0.1", "10") # fails on command
handleRequest("", "DOTHIS", "11C", "127.0.0B.1", "A10") # fails on arguments
I used the "\d" regex shortcut in python for numbers, I also made each check explicit so if it does fail you know why. If you are passing in arguments that are not strings you can use str(argX) to convert it to a string before checking. I used python 2.7 to test this.
EDIT:
I should also point out, that I lazily did not make this method part of a class, and just passed in the empty string for self.
re.match("^[0-9.]+$", number)
matches all strings that contain only numbers.
So you should be able to do:
def handleRequest(self, command = '0', ident = '0', ip = '0', duration='0'):
use help('re') to find out about what the characters mean.

Categories

Resources