syntax error near unexpected token `<' from Applescript to Python - python

I am using the following command to pass a string to python from Applescript
String mytext contains the HTML body of an email starting with <...
Applescript
display dialog (do shell script "/Users/mymac/Documents/'Microsoft User Data'/'Outlook Script Menu Items'/ test.py" & mytext)
Python
#!/usr/bin/env python
import sys
import string
def main():
print sys.argv[1:]
if __name__ == "__main__":
main()
How can I rectify this error?

You don't want to pass the HTML as an argument to the Python script. Instead, do something like:
display dialog (do shell script "/Users/mymac/Documents/'Microsoft User Data'/'Outlook Script Menu Items'/ test.py < webpage.html")
print sys.stdin.read()

The problem is you are executing a shell script ... by constructing a long line of text.
"/Users/mymac/Documents/'Microsoft User Data'/'Outlook Script Menu Items'/ test.py" & " ... ")
but the "<" sign and the ">" sign have a special meaning for the shell.

Related

Passing a list as variable to python script from bash script

I have a python script like below.
# Import necessary libraries and functions
import sys
import traceback
y = '2020'
querysting = "select {} from table where Year={}".format(col_list,y)
df = pd.read_sql(querystring,db)
if __name__ == '__main__':
if len(sys.argv) != 8:
print('Invalid number of args......')
print('Usage: file.py Input_path Output_path')
exit()
_, col_list, FinalDB, final_table, host, dsl_tbl_name, username, password = tuple(sys.argv)
data_load(col_list, FinalDB, final_table, host, tbl_name, username, password)
Now I am calling this python script inside a shell script like below
#!/bin/bash
col_list='id, name, address, phone_number'
FinalDB='abc'
final_table='xyz'
host='xxxxxx.xxxx'
tbl_name='test'
username='USER'
password='test_pass'
python python_script.py ${col_list} ${FinalDB} ${final_table} ${host} ${tbl_name} ${username} ${password}
Now when I run this bash script I am getting Invalid number of args...... error
I am pretty much sure that it is some thing to do with col_list variable being passed to the python script.
Because instead of having columns in a list if I just pass select * in the query and removing col_list variable then I don't get any errors
What am I doing wrong here and how can I resolve this issue.
The problem comes from how you pass your variables that contains spaces from Bash to Python.
You may note that:
In shell scripts command line arguments are separated by
whitespace, unless the arguments are quoted.
Let's have this simple Python script:
python_script.py:
import sys
if __name__ == '__main__':
print(sys.arv)
Then in your Terminal:
$> export var1="hello"
$> python python_script.py $var1
['python_script.py', 'hello']
However:
$> export var1="hello, hi"
$> python python_script.py $var1
['python_script.py', 'hello,', 'hi'] # Note Here: Two args were passed
$> export var1="hello,hi"
$> python python_script.py $var1
['python_script.py', 'hello,hi'] # One arg passed
So, a solution to your problem, is to pass your Bash args as a string even with spaces, like this example:
$> export var1="hello, hi, hola"
$> python python_script.py "$var1"
['python_script.py', 'hello, hi, hola']
For more informations see this article

Using Applescript to fire python script

I'm trying to use Applescript to fire a python script. When I fire it from terminal, everything works fine, but when I fire from Applescript, it appears to run but nothing happens.
I've tried all manner of combinations for everything I can find in searches and other posts for using "python file.py" or "/usr/bin/python file.py" with "#!/usr/bin/env python" and "#!/usr/bin/python".
If I enter "which python" in terminal, I get "/usr/bin/python"
Right now I have both scripts broken down to their base components. I'll eventually be using Applescript to pass a file path into python using sys.argv[1] (which is why I'm using Applescript to fire the python script) but I'm not even that far along yet as the below doesn't work yet.
Applescript
do shell script "/usr/bin/python $HOME/Desktop/test.py"
Python
#!/usr/bin/python
import sys
import os
# The notifier function
def notify(title, subtitle, message):
t = '-title {!r}'.format(title)
s = '-subtitle {!r}'.format(subtitle)
m = '-message {!r}'.format(message)
os.system('terminal-notifier {}'.format(' '.join([m, t, s])))
# Calling the function
notify(title = 'Message Test',
subtitle = 'Test1:',
message = 'Test2')
sys.exit(0)
The python script sends a notifier message. Every time I run in terminal, I receive the message without issue. Every time I run the applescript to do as shell script it runs without error-ing in AS, but no message comes from Python.
Anyone have thoughts on where I've gone wrong?
Does it work for you if you use a full path to the binary? It worked for me in both BBEdit and Smile (script editor). My path is:
/Applications/terminal-notifier-2.0.0/terminal-notifier.app/Contents/MacOS/terminal-notifier
So I used:
#!/usr/bin/python
import sys
import os
# The notifier function
def notify(title, subtitle, message):
t = '-title {!r}'.format(title)
s = '-subtitle {!r}'.format(subtitle)
m = '-message {!r}'.format(message)
os.system('/Applications/terminal-notifier-2.0.0/terminal-notifier.app/Contents/MacOS/terminal-notifier {}'.format(' '.join([m, t, s])))
# Calling the function
notify(title = 'Message Test',
subtitle = 'Test1:',
message = 'Test2')
sys.exit(0)

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.

Is it possible to take repeated command line inputs in python untill user exits explicitly

import sys
import commands
from optparse import OptionParser
def sample():
parser.add_option("-a", "--accept",
action="store",
dest="accept",
type="str",
help="Accept or quit")
options, args = parser.parse_args()
if(options.accept != None) and (options.accept == "123"):
print "Hello! code accepted!"
elif(options.accept == "quit"):
break
So when I execute this small script in the format python sample.py -a 123, it prints Hello! code accepted! and then it exits, but I want it to repeatedly keep executing the script untill I keep executing in the format python sample.py -a 123. It should only exit when I give 'quit' in the command line options.
Current output:-
#python sample.py -a 123
Hello!Code accepted!
#
Expected output:-
#python sample.py -a 123
Hello!Code accepted!
python sample.py -a 123
Hello!Code accepted!
python sample.py -a 123
Hello!Code accepted!
python sample.py -a quit
#
Any help? Thanks
There is a python module specifically for creating command line applications -- Cmd. It was featured in PyMOTW (Python module of the week) quite a while back. With just a few lines of code you can have a complete console app with online help, autocomplete, and a REPL (read-eval-print loop). The PyMOTW article has a decent little tutorial. See http://pymotw.com/2/cmd/

How can I tell whether screen is running?

I am trying to run a Python program to see if the screen program is running. If it is, then the program should not run the rest of the code. This is what I have and it's not working:
#!/usr/bin/python
import os
var1 = os.system ('screen -r > /root/screenlog/screen.log')
fd = open("/root/screenlog/screen.log")
content = fd.readline()
while content:
if content == "There is no screen to be resumed.":
os.system ('/etc/init.d/tunnel.sh')
print "The tunnel is now active."
else:
print "The tunnel is running."
fd.close()
I know there are probably several things here that don't need to be and quite a few that I'm missing. I will be running this program in cron.
from subprocess import Popen, PIPE
def screen_is_running():
out = Popen("screen -list",shell=True,stdout=PIPE).communicate()[0]
return not out.startswith("This room is empty")
Maybe the error message that you redirect on the first os.system call is written on the standard error instead of the standard output. You should try replacing this line with:
var1 = os.system ('screen -r 2> /root/screenlog/screen.log')
Note the 2> to redirect standard error to your file.

Categories