How to call a specific Python function from a batch file? - python

Let's say I have this simple Python script, named MyScript.py:
def MyFunction(someInput):
#Do something with input
I would like to write a batch file that specifically calls MyFunction from MyScript with someInput.
Now, I could do some Python-foo and add:
import sys
def MyFunction(someInput):
#Do something with input
if __name__ == "__main__":
eval(sys.argv[1])
Then I can use a batch like this:
python MyScript.py MyFunction('awesomeInput')
pause
But I have a feeling there's a more obvious solution here that doesn't involve me retrofitting "_name_ == "_main_" logic in each of my scripts.

If you are in the same folder as the script you can do:
python -c "import Myscript;Myscript.MyFunction('SomeInput')"

Indeed. You can use the -c (command) argument.
python -c "import MyScript; MyScript.MyFunction('someInput')"

You could write a batch file using this trick:
#echo off
rem = """
rem Do any custom setup like setting environment variables etc if required here ...
python -x "%~f0" %*
goto endofPython """
# Your python code goes here ..
from MyScript import MyFunction
MyFunction('awesomeInput')
rem = """
:endofPython """

my_function.py:
import sys
def MyFunction(someInput):
print 'MyFunction:', someInput
#Do something with input
if __name__ == "__main__":
pass
you call it from shell with:
python -c 'from my_function import MyFunction ; MyFunction("hello")'

Related

Passing Python Variables to Powershell Script

I'm looking to pass variables from a Python script into variables of a Powershell script without using arguments.
var_pass_test.py
import subprocess, sys
setup_script = 'C:\\Users\\user\\Desktop\\Code\\Creation\\var_pass_test.ps1'
test1 = "Hello"
p = subprocess.run(["powershell.exe",
setup_script], test1,
stdout=sys.stdout)
var_pass_test.ps1
Write-Host $test1
How would one go about doing this such that the Powershell script receives the value of test1 from the Python script? Is this doable with the subprocess library?
To pass arguments verbatim to the PowerShell CLI, use the -File option: pass the script-file path first, followed by the arguments to pass to the script.
In Python, pass all arguments that make up the PowerShell command line as part of the first, array-valued argument:
import subprocess, sys
setup_script = 'C:\\Users\\user\\Desktop\\Code\\Creation\\var_pass_test.ps1'
test1 = "Hello"
p = subprocess.run([
"powershell.exe",
"-File",
setup_script,
test1
],
stdout=sys.stdout)

Python's sh module - is it at all possible for a script to request input?

Using Python's sh, I am running 3rd party shell script that requests my input (not that it matters much, but to be precise, I'm running an Ansible2 playbook with the --step option)
As an oversimplification of what is happening, I built a simple bash script that requests an input. I believe that if make this simple example work I can make the original case work too.
So please consider this bash script hello.sh:
#!/bin/bash
echo "Please input your name and press Enter:"
read name
echo "Hello $name"
I can run it from python using sh module, but it fails to receive my input...
import errno
import sh
cmd = sh.Command('./hello.sh')
for line in cmd(_iter=True, _iter_noblock=True):
if line == errno.EWOULDBLOCK:
pass
else:
print(line)
How could I make this work?
After following this tutorial, this works for my use case:
#!/usr/bin/env python3
import errno
import sh
import sys
def sh_interact(char, stdin):
global aggregated
sys.stdout.write(char)
sys.stdout.flush()
aggregated += char
if aggregated.endswith(":"):
val = input()
stdin.put(val + "\n")
cmd = sh.Command('./hello.sh')
aggregated = ""
cmd(_out=sh_interact, _out_bufsize=0)
For example, the output is:
$ ./testinput.py
Please input your name and press Enter:arod
Hello arod
There are two ways to solve this:
Using _in:
using _in, we can pass a list which can be taken as input in the python script
cmd = sh.Command('./read.sh')
stdin = ['hello']
for line in cmd(_iter=True, _iter_noblock=True, _in=stdin):
if line == errno.EWOULDBLOCK:
pass
else:
print(line)
Using command line args if you are willing to modify the script.

How to make linux command for the python program using shell script by giving arguments?

For example I have python files like hello.py, add.py, square.py.
Definitions of these files are
hello.py:-
def hello(a):
print a #a is some name
add.py:-
def add(a,b):
print a+b #where a,b are numbers which I have to pass as arguments in command
square.py:-
def square(a):
print a**2 #where 'a' is a number
I want to execute these files from shell script(For example pyshell.sh) and want to make commands like
pyshell --hello name - then it has to execute hello.py
pyshell --add 4 5 - then it has to execute add.py
pyshell --square 2 - then it has to execute square.py
I am trying with this code
#! /usr/bin/python
import argparse
# Create Parser and Subparser
parser = argparse.ArgumentParser(description="Example ArgumentParser")
subparser = parser.add_subparsers(help="commands")
# Make Subparsers
hai_parser = subparser.add_parser('--hai', help='hai func')
hai_parser.add_argument("arg",help="string to print")
hai_parser.set_defaults(func='hai')
args = parser.parse_args()
def hai(arg):
print arg
if args.func == '--hai':
hai(args.arg)
But I am getting an error like
usage: 1_e.py [-h] {--hai} ...
1_e.py: error: invalid choice: 'name' (choose from '--hai')
Here's an example using argparse all in python.
You can run it by with the following:
python pyshell.py hello "well hi"
python pyshell.py add 20 3.4
python pyshell.py square 24
pyshell.py:-
import argparse
# Create Parser and Subparser
parser = argparse.ArgumentParser(description="Example ArgumentParser")
subparser = parser.add_subparsers(help="commands")
# Make Subparsers
hello_parser = subparser.add_parser('hello', help='hello func')
hello_parser.add_argument("arg",help="string to print")
hello_parser.set_defaults(func='hello')
add_parser = subparser.add_parser('add', help="add func")
add_parser.add_argument("x",type=float,help='first number')
add_parser.add_argument("y",type=float,help='second number')
add_parser.set_defaults(func='add')
square_parser = subparser.add_parser('square', help="square func")
square_parser.add_argument("a",type=float,help='number to square')
square_parser.set_defaults(func='square')
args = parser.parse_args()
def hello(arg):
print arg
def add(x,y):
print x + y
def square(a):
print a**2
if args.func == 'hello':
hello(args.arg)
elif args.func == 'add':
add(args.x,args.y)
elif args.func == 'square':
square(args.a)
You can use shebang inside python scripts like #! /usr/bin/python such that those files can be executed like shell script for example python file.py can be executed as file.py if you use shebang. So according to your question you can call those scripts in switch case in shell scripts like this
#! /bin/bash
case ${1:-''} in
"hello")
/path/to/hello $2
;;
"add")
/path/to/add $2 $3
;;
"square")
/path/to/square $2
;;
*)
echo "Invalid option supplied"
exit 1
;;
exit 0
If you don't use shebang in python script add python in front of /path/to/script.py better use shebang in script and use absolute path. Also make sure that the respective scripts has execute permissions.

How to handle python raw_input() in batch file

I created a batch file to run files in sequence, however my python file takes in an input (from calling raw_input), and I am trying to figure out how to handle this over the batch file.
run.bat
The program doesn't proceed to the next line after the .py file is executed, for brevity i just just showed necessary commands
cd C:\Users\myname\Desktop
python myfile.py
stop
myfile.py
print ("Enter environment (dev | qa | prod) or stop to STOP")
environment = raw_input()
Here's a solution.
Take your myfile.py file, and change it to the following:
import sys
def main(arg = None):
# Put all of your original myfile.py code here
# You could also use raw_input for a fallback, if no arg is provided:
if arg is None:
arg = raw_input()
# Keep going with the rest of your script
# if __name__ == "__main__" ensures this code doesn't run on import statements
if __name__ == "__main__":
#arg = sys.argv[1] allows you to run this myfile.py directly 1 time, with the first command line paramater, if you want
if len(sys.argv) > 0:
arg = sys.argv[1]
else:
arg = None
main(arg)
Then create another python file, called wrapper.py:
#importing myfile here allows you to use it has its own self contained module
import sys, myfile
# this loop loops through the command line params starting at index 1 (index 0 is the name of the script itself)
for arg in sys.argv[1 : ]:
myfile.main(arg)
And then at the command line, you can simply type:
python wrapper.py dev qa prod
You could also put the above line of code in your run.bat file, making it look at follows:
cd C:\Users\myname\Desktop
python wrapper.py dev qa prod
stop
the question is not related to python. To your shell. According http://ss64.com/nt/syntax-redirection.html cmd.exe uses the same syntax as unix shell (cmd1 | cmd2), so your bat file should work fine when called with command, which will send the file content to standard output.
Edit: added example
echo "dev" | run.bat
C:\Python27\python.exe myfile.py
Enter environment (dev | qa | prod) or stop to STOP
environment="dev"

Reading constants values from python file and using it in a shell

PatchConstants.py:
class PatchConstants:
PATCHHOME='/scratch/app/product/fmw/obpinstall/patching'
FMWHOME='/scratch/app/product/fmw'
DOMAINPATH=FMWHOME+'/user_projects/domains/'
def __init__(self):
pass
b.sh:
from PatchConstants import PatchConstants
path = PatchConstants.PATCHHOME
I want to extract python constant variable in a shell scripts.
Is it possible?
You can try the -c option of python to run python commands and deliver the result to the shell variable.
Just like:
path = $(python -c "from PatchConstants import PatchConstant ; print PatchConstants.PATCHHOME")

Categories