Ritashugisha Posted April 13, 2014 Posted April 13, 2014 I've run into a problem when trying to execute a Python script in Alfred. The script is basically running a subprocess using a program located at /opt/random/bin/. When I run the script, I get the following debug. [ERROR: alfred.workflow.action.script] Code 127: /bin/bash: /opt/random/bin/tool "/Users/ritashugisha/Downloads/file.txt" "/Users/ritashugisha/Downloads/new.txt": No such file or directory So I looked at the $PATH that Alfred was using... bump = open('/Users/ritashugisha/Desktop/path.txt', 'w') proc = subprocess.Popen(['echo $PATH'], stdout = subprocess.PIPE, shell = True) (proc, proc_e) = proc.communicate() bump.write(str(proc)) bump.close() and found the following: /usr/bin:/bin:/usr/sbin:/sbin This doesn't include what I need it to include. So do you have any ideas for tricks to get around this? Or am I approaching this the wrong way? Thanks for any help you provide!
Ritashugisha Posted April 13, 2014 Author Posted April 13, 2014 (edited) So I've fixed the $PATH to also use the /opt/random/bin path as well... /usr/bin:/bin:/usr/sbin:/sbin:/opt/random/bin via... os.environ['PATH'] = '%s:/opt/random/bin' % os.environ['PATH'] But for some reason I'm still getting the Alfred debug error and my script is still not working. Edited April 13, 2014 by Ritashugisha
deanishe Posted April 13, 2014 Posted April 13, 2014 Could you post the code that's actually causing the error? It could be several things.
Ritashugisha Posted April 13, 2014 Author Posted April 13, 2014 import os, sys import ToolUtil def convertSelect(query): if len(query) > 0 and query[0] == '.': query = query[1:] feed = ToolUtil.Feedback() # Feedback for Script Filter item = ToolUtil.getFinderSelection() # Gets the current selected item in Finder via Applescript formatFound = False if os.path.splitext(item)[1][1:].lower() in ToolUtil.SUPPORTED_FORMATS: # Checks if the selected item in Finder is in an array of legal extensions for i in ToolUtil.SUPPORTED_FORMATS: if query.lower() in i: feed.add_item(u'%s \u279c .%s' % (os.path.basename(item), i), 'Convert to %s' % i, 'tool "%s" "%s"' % (item, '%s.%s' % (os.path.splitext(item)[0], i)), # Script filter argument '', '', 'icon.png') formatFound = True else: feed.add_item('Selection cannot be converted', '', '', '', '', 'icon.png') formatFound = True if not formatFound: feed.add_item('Format .%s does not exist' % query, '', '', '', '', 'icon.png') return feed The feedback is then listed in the script filter, and whatever the user selects from the script filter gets passed to the following method... import os, subprocess os.environ['PATH'] = '%s:/opt/random/bin' % os.environ['PATH'] proc = subprocess.Popen(['{query}'], stdout = subprocess.PIPE, shell = True) (proc, proc_e) = proc.communicate() return proc Hope this helps.
deanishe Posted April 14, 2014 Posted April 14, 2014 (edited) Yeah, the problem is in the way you're passing stuff to subprocess.Popen. First of all, you really shouldn't be using shell=True unless absolutely necessary. Here it isn't. Use the full path of the executable instead. With subprocess.Popen (and .call, .check_output etc.), you're supposed to pass the program as the first item in the args list and subsequent arguments in the rest of args. You don't mash them all together like with os.system or the exec functions in other languages. The error you were getting is because you're passing "/Users/ritashugisha/Downloads/file.txt" "/Users/ritashugisha/Downloads/new.txt" as a single argument (and hence filepath), not two separate arguments. If you absolutely have to pass multiple arguments in one {query}, this line: 'tool "%s" "%s"' % (item, '%s.%s' % (os.path.splitext(item)[0], i)) should look something more like this: DELIMITER = '➜' '/full/path/to/tool {0} {1} {0} {2}.{3}'.format(DELIMITER, item, os.path.splitext(item)[0], i) (I don't know if you've got from __future__ import unicode_literals at the top of your script, but if you haven't this code will break, as will your code with non-ASCII data. Change DELIMITER = '➜' to DELIMITER = u'➜' if you don't want it to break immediately, add from __future__ import unicode_literals (or prepend every literal strings with u) if you don't want your code to break with non-ASCII input, too.)And the following script should split the query into the individual arguments and pass those to subprocess.Popen: import subprocess DELIMITER = '➜' args = [s.strip() for s in '{query}'.split(DELIMITER)] proc = subprocess.Popen(args, stdout=subprocess.PIPE) (proc, proc_e) = proc.communicate() return proc Note: I'm drunk and haven't tested my code. No liability is accepted for errors in my code, but the basis of the error is 100% correct. I guarantee it!If it's not working at all, ask me again, and I'll sort it out in ~8 hours or so when I'm sober Also, it's perhaps worth adding that your code formatting isn't compliant with PEP8 (no extra spaces around = in assignments, for example). It's not a big deal—not by a long way—but it's kinda expected. Edited April 14, 2014 by deanishe
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now