Jump to content

Q: Choosing between "Run Script" (bash) v. "Run Script" (osascript) v. "Run NSAppleScript"

Recommended Posts

Caveat: I'm completely new to Alfred Workflows, so this is probably a really basic set of questions...


Historically, I've created bash scripts to start and stop a variety of servers on my Macs which I use, in part, for Web application development. These servers might include virtual machines, different Tomcat instances, mail servers, etc. None of them run by default, and none run on low port numbers so none have to be started/stopped using elevated privileges. When I want to start or stop one or more of these servers, I open a terminal window and invoke my various bash scripts with needed arguments, etc.


I would now like to set up Alfred Workflows for this same sort of activity, so that I can eliminate the step of having to open the terminal window.


I've poked at the Alfred Workflows capability enough over the past couple days to figure out that I can get what I want in a variety of ways:


1. keyword/with space/argument required + Run NSAppleScript, where the AppleScript just invokes my existing bash scripts with the keyword arguments


2. keyword/with space/argument required + Run Script (/usr/bin/osascript), where the AppleScript again just invokes my existing bash scripts with the keyword arguments


3. keyword/with space/argument required + Run Script (/bin/bash), where I basically embed my existing bash script within the workflow and explode {query} to get the keyword argument available like the arguments I would provide to my existing bash scripts on the terminal command-line.


I've convinced myself all of these approaches would work.


My question is primarily related to the benefits and/or drawbacks of these different approaches: Are there performance differences or system impacts (speed, memory, other?) between these three approaches that I should consider in choosing one approach over the others? I understand, for instance, that the difference between 1 and 2 is that 1 runs on the Alfred thread, while 2 does not... but what does that mean in real terms for me and my system if the script takes a few seconds to complete? Does just embedding the bash script directly in the workflows help with efficiency/impact, as AppleScript is no longer in the picture?


Does any of this really matter?


Any insight and recommendations about the implications of the different approaches would be great.


Thanks in advance.





Link to comment

My thinking is, if you're using multiple Macs, then embed the scripts in the workflow so Alfred & Dropbox (I sync my Alfred prefs in Dropbox) will take care of the synchronization for, so there's no need to worry about keeping track of separate copies on each Mac.  But if you have another sync solution that's working, this isn't necessarily an advantage.


An advantage to options 1 & 2 over 3 is that it's just easier to edit the scripts in your usual coding setup rather than in the Alfred workflow sheets.


If you were distributing the workflow publicly, option 3 might be the best choice since you obviously want to include your scripts in the workflow.  But...I'd actually use an option 4 here, which would be to call the scripts as in option 1 or 2 (for the reason described in the last paragraph), but to put them in the workflow folder (so that they come with the workflow) rather than keep them in their existing location.  


I've been using osascript for all my recent workflows rather than run NSAppleScript mostly b/c I am working up stuff from scratch (often with a lot of trial and error) and don't want Alfred to hang if something goes wrong with the script.  If you can anticipate a situation where a server might not respond, e.g., and leave your script hanging, I'd go with osascript.  With the exception of this possibility, I don't think the performance differences are going to be noticeable in everyday use.

Edited by dfay
Link to comment

@dfay: Thanks for the follow-up, all good points.


I'm definitely leaning toward the approach of having the scripts included within the workflow, just for my own sanity across my different systems. I don't envision distributing them publicly; these are likely so specific to how I configure and use my development systems that I can't imagine even co-workers finding them particularly valuable.


There's an aspect of simplicity, too, to just running them via bash -- as opposed to using AppleScript to run bash scripts -- that appeals to me, as well. Fewer layers...

Link to comment
  • 2 weeks later...

Aye, you should stay away from AppleScript (and especially NSAppleScript). Using an AppleScript to run your bash scripts just adds unnecessary indirection.

You shouldn't need to parse {query}. Just omit the quotes in the Script box (i.e. use {query}, not "{query}"), and bash will see {query} as individual arguments.

Link to comment

@deanishe: Thanks for the follow-up.


I did decide to go with just bash, rather than either of the other two. I'm using "read -a" to explode {query} into an array of the arguments for use within the script, which makes migrating my scripts from use on a command-line into Alfred workflows really simple.

Link to comment

@deanishe: OK, now I think I get the idea of having the scripts in the workflow directory; @dfay touched on it in his response, above, too, but it didn't mean enough to me to pull that thread.


I'm definitely still figuring this out, but I now have the bash scripts saved as separate files in the workflow directory and the "Run Script" action for each keyword just "dots" those scripts with {query} (e.g., something like . ./vm {query} to run my "vm" script to start and stop VMs with whatever other stuff I have included when I invoked it).


Is that the approach the two of you were referring to?




Link to comment

Yeah, I think so. Your workflow's root directory (where info.plist is) is the current working directory when Alfred runs your workflow, so you can run any scripts inside it easily.
You always set the Language to /bin/bash and treat the Script box like a command line.
Using scripts instead of Alfred's Script box makes writing your code a lot easier because you can use a proper code editor and easily track down errors by line number. Also, git etc. don't work so well when everything is embedded in info.plist.
With regard to {query}, what you normally do (when Language = /bin/bash) is use "{query}" (i.e. in double quotes), and select Backquote, Double Quotes, Backslashes and Dollars for the Escaping options to ensure {query} reaches your script untouched by bash.
If {query} is actually a list of command-line options to a script, then yeah, just use {query} without quotes, and turn off all Escaping options, too.

Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...