Passing arguments to a embedded python script in bash - python

I'm having difficulties passing arguments to a embedded bash script.
#!/bin/bash/
function my_function() {
MYPARSER="$1" python - <<END
<<Some Python Code>>
class MyParser(OptionParser):
def format_epilog(self, formatter):
return self.epilog
parser=MyParser(version=VER, usage=USAGE, epilog=DESC)
parser.add_option("-s", "--Startdir", dest="StartDir",
metavar="StartDir"
)
parser.add_option("-r", "--report", dest="ReportDir",
metavar="ReportDir"
)
<<More Python Code>>
END
}
foo="-s /mnt/folder -r /storagefolder/"
my_function "$foo"
I've read Steve's Blog: Embedding python in bash scripts which helped but I'm still unable to pass the argument. I've tried both parser and myparser as environmental variables.
Is it as simple as defining $2 and passing them individually?
Thanks

You're overcomplicating this rather a lot. Why mess with a parser where
value="hello" python -c 'import os; print os.environ["value"]'
Or, for a longer script:
value="hello" python <<'EOF'
import os
print os.environ["value"]
EOF
If you need to set sys.argv for compatibility with existing code:
python - first second <<<'import sys; print sys.argv'
Thus:
args=( -s /mnt/folder -r /storagefolder/ )
python - "${args[#]}" <<'EOF'
import sys
print sys.argv # this is what an OptionParser will be looking at by default.
EOF

Related

Passing Python variable as argument to shell script

I have a python code in which I need to run a shell script by passing arguments. Below is my code
#!/usr/bin/env python3
import subprocess
import os
import sys
filename=sys.argv[1]
subprocess.call(['bash','./shell.sh',filename])
print("Successfully completed")
Here I am trying to get an input as an argument while running ./file.py (filename) .But If I try to pass that as an argument to the shell script I am not able exceute the prograam.
Also I tried the code below
#!/usr/bin/env python3
import subprocess
import shlex
import sys
filename=sys.argv[1]
subprocess.call(shlex.split('./shell2.sh filename'))
For the above code I am getting error like this:
awk: fatal: cannot open file `filename' for reading (No such file or directory)
My script code:
file=$1
awk '{
if($0 ~ /LogType/){
if(hold ~ /LogType:stderr/){
print hold;
}
hold=$0
}else{
if($0 ~ /ERROR/ || $0 ~/WARN/){hold=hold "\n" $0 ": line " NR}else{hold=hold "\n" $0}
}
}END{
if(hold ~ /LogType:stderr/){
print hold
}
}' $file | sed -n -e 's/^.*LogType:\(stderr\)$/\1/p' \
-e 's/^.*Log Upload Time :\(.*\)/\1/p' \
-e 's/^.*LogLength:\(.*\)$/\1/p' \
-e 's/^.*\(ERROR\|WARN\).*$/\0/p'
How should I pass an input value to a shell script.Kindly help me to solve this issue .Thanks a lot!

return value from python script to shell script

I am new in Python. I am creating a Python script that returns a string "hello world." And I am creating a shell script. I am adding a call from the shell to a Python script.
i need to pass arguments from the shell to Python.
i need to print the value returned from Python in the shell script.
This is my code:
shellscript1.sh
#!/bin/bash
# script for testing
clear
echo "............script started............"
sleep 1
python python/pythonScript1.py
exit
pythonScript1.py
#!/usr/bin/python
import sys
print "Starting python script!"
try:
sys.exit('helloWorld1')
except:
sys.exit('helloWorld2')
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 $?
You can also use exit() without sys; one less thing to import. Here's an example:
$ python
>>> exit(1)
$ echo $?
1
$ python
>>> exit(0)
$ echo $?
0

How to parse JSON passed on the command line

I am trying to pass JSON parameters through command line in Python:
automation.py {"cmd":"sel_media","value":"5X7_photo_paper.p}
how can I extract the values sel_media and 5X7_photo_paper.p?
I used the following code, but it is not working:
cmdargs = str(sys.argv[1])
print cmdargs
Provided you pass actual valid JSON to the command line and quote it correctly, you can parse the value with the json module.
You need to quote the value properly, otherwise your shell or console will interpret the value instead:
automation.py '{"cmd":"sel_media","value":"5X7_photo_paper.p"}'
should be enough for a bash shell.
In Python, decode with json.loads():
import sys
import json
cmdargs = json.loads(sys.argv[1])
print cmdargs['cmd'], cmdargs['value']
Demo:
$ cat demo.py
import sys
import json
cmdargs = json.loads(sys.argv[1])
print cmdargs['cmd'], cmdargs['value']
$ bin/python demo.py '{"cmd":"sel_media","value":"5X7_photo_paper.p"}'
sel_media 5X7_photo_paper.p
The above is generally correct, but I ran into issues with it when running on my own python script
python myscript.py '{"a":"1"}'
does not work directly in my terminal
so I did
python myscript.py '{\"a\":\"1\"}'

Python script for changing windows path to unix path

I want a script where I can paste a windows path as argument, and then the script converts the path to unix path and open the path using nautilus.
I want to be able to use the script as follows:
mypythonscript.py \\thewindowspath\subpath\
The script currently looks like this:
import sys, os
path = "nautilus smb:"+sys.argv[1]
path = path.replace("\\","/")
os.system(path)
I almost works :)
The problem is that I have to add ' around the argument... like this:
mypythonscript.py '\\thewindowspath\subpath\'
Anyone who knows how I can write a script that allows that argument is without ' , ... i.e. like this:
mypythonscript.py \\thewindowspath\subpath\
EDIT: I think I have to add that the problem is that without ' the \ in the argument is treated as escape character. The solution does not necessarily have to be a python script but I want (in Linux) to be able to just paste a windows path as argument to a script.
Unless you're using a really early version of Windows: "/blah/whatever/" just works for your OP.
Actually I had something like this a while ago, I made a bash script to automatically download links I copy into clipboard, here it is edited to use your program (you first need to install xclip if you don't already have it):
#!/bin/bash
old=""
new=""
old="$(xclip -out -selection c)"
while true
do
new="$(xclip -out -selection c)"
if [ "$new" != "$old" ]
then
old="$new"
echo Found: $new
mypythonscript.py $new
fi
sleep 1
done
exit 0
Now whenever you copy something new into the clipboard, your Python script will be executed with an argument of whatever is in your clipboard.
To avoid dealing with escapes in the shell you could work with the clipboard directly:
import os
try:
from Tkinter import Tk
except ImportError:
from tkinter import Tk # py3k
# get path from clipboard
path = Tk().selection_get(selection='CLIPBOARD')
# convert path and open it
cmd = 'nautilus'
os.execlp(cmd, cmd, 'smb:' + path.replace('\\', '/'))
ntpath, urlparse, os.path modules might help to handle the paths more robustly.
#!/usr/bin/python
#! python3
#! python2
# -*- coding: utf-8 -*-
"""win2ubu.py changes WINFILEPATH Printing UBUNTU_FILEPATH
Author: Joe Dorocak aka Joe Codeswell (JoeCodeswell.com)
Usage: win2ubu.py WINFILEPATH
Example: win2ubu.py "C:\\1d\ProgressiveWebAppPjs\\Polymer2.0Pjs\\PolymerRedux\\zetc\\polymer-redux-polymer-2"
prints /mnt/c/1d/ProgressiveWebAppPjs/Polymer2.0Pjs/PolymerRedux/zetc/polymer-redux-polymer-2
N.B. spaceless path needs quotes in BASH on Windows but NOT in Windows DOS prompt!
"""
import sys,os
def winPath2ubuPath(winpath):
# d,p = os.path.splitdrive(winpath) # NG only works on windows!
d,p = winpath.split(':')
ubupath = '/mnt/'+d.lower()+p.replace('\\','/')
print (ubupath)
return ubupath
NUM_ARGS = 1
def main():
args = sys.argv[1:]
if len(args) != NUM_ARGS or "-h" in args or "--help" in args:
print (__doc__)
sys.exit(2)
winPath2ubuPath(args[0])
if __name__ == '__main__':
main()
may want to try
my_argv_path = " ".join(sys.argv[1:])
as the only reason it would split the path into separate args is spaces in pasted path
(eg: C:\Program Files would end up as two args ["c:\Program","Files"])

Is there a way to make python become interactive in the middle of a script?

I'd like to do something like:
do lots of stuff to prepare a good environement
become_interactive
#wait for Ctrl-D
automatically clean up
Is it possible with python?If not, do you see another way of doing the same thing?
Use the -i flag when you start Python and set an atexit handler to run when cleaning up.
File script.py:
import atexit
def cleanup():
print "Goodbye"
atexit.register(cleanup)
print "Hello"
and then you just start Python with the -i flag:
C:\temp>\python26\python -i script.py
Hello
>>> print "interactive"
interactive
>>> ^Z
Goodbye
The code module will allow you to start a Python REPL.
With IPython v1.0, you can simply use
from IPython import embed
embed()
with more options shown in the docs.
To elaborate on IVA's answer: embedding-a-shell, incoporating code and Ipython.
def prompt(vars=None, message="welcome to the shell" ):
#prompt_message = "Welcome! Useful: G is the graph, DB, C"
prompt_message = message
try:
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed(argv=[''],banner=prompt_message,exit_msg="Goodbye")
return ipshell
except ImportError:
if vars is None: vars=globals()
import code
import rlcompleter
import readline
readline.parse_and_bind("tab: complete")
# calling this with globals ensures we can see the environment
print prompt_message
shell = code.InteractiveConsole(vars)
return shell.interact
p = prompt()
p()
Not exactly the thing you want but python -i will start interactive prompt after executing the script.
-i : inspect interactively after running script, (also PYTHONINSPECT=x) and force prompts, even if stdin does not appear to be a terminal
$ python -i your-script.py
Python 2.5.4 (r254:67916, Jan 20 2010, 21:44:03)
...
>>>
You may call python itself:
import subprocess
print "Hola"
subprocess.call(["python"],shell=True)
print "Adios"

Categories

Resources