Jump to content

Accessing workflow args in bash script


Recommended Posts

Hi - I am trying to run a bash script and pass in 3 args from and Alfred keyword input type. I want to validate the input and exit if 3 args are not passed.

 

The issue I have is that when using "with input as argv" bash only sees a single argument, ie. I can't then do something like:

if [ "$#" -ne 3 ]; then
  echo "3 arguments required"
  exit 1
fi

because bash only sees a single arg verified with a test script:

echo "$#" > /Users/ilium007/sandpit/ilium007.txt
echo $@ >> /Users/ilium007/sandpit/ilium007.txt

which results in:

04:44 pm ilium007@MBP ~/sandpit
$ cat ilium007.tst
1
a s d f g

ie. 1 arg passed when I actually passed in 5 args

 

 

I wrote a seperate bash script (external to Alfred) to test my code and it works as expected:

04:51 pm ilium007@MBP ~/sandpit
$ cat test1.sh
#!/bin/bash

echo "$#" > /Users/ilium007/sandpit/ilium007.txt
echo $@ >> /Users/ilium007/sandpit/ilium007.txt

04:51 pm ilium007@MBP ~/sandpit
$

and then call it passing in 5 args:

04:50 pm ilium007@MBP ~/sandpit
$ ./test1.sh a s d f g
04:50 pm ilium007@MBP ~/sandpit
$ cat ilium007.txt
5
a s d f g
04:50 pm ilium007@MBP ~/sandpit
$

How should I be doing this from within Alfred ? Do I need to read into a bash list and then look at the length of the list ?

Edited by ilium007
Link to comment

The only time Alfred passes multiple arguments in argv is when it's calling a File Action with multiple files.
 
In every other situation, Alfred cannot possibly know whether your input is one single argument containing spaces or multiple arguments. So it passes the entire input as $1, which is usually the right thing to do (Alfred isn't a shell and relatively few workflows treat it like one).
 
The simplest solution is to save your script to a separate file in the workflow directory and call it from Alfred's Script box: 

# Input as argv
./myscript.sh $1
 
# Input as query macro
./myscript.sh {query}

Because $1 or {query} are not in double quotes, any spaces in the input will cause bash to call myscript.sh with multiple arguments, so $1, $2, $@ etc. will work the way you want.

Edited by deanishe
Link to comment

No, I am re-thinking how I approach it. I don't want external scripts, I was doing it in Alfred so I could just manage a workflow plugin. In the Linux world args passed to scripts are space delimited. Not sure why Alfred decided to do it different. Maybe it was ease of input in the GUI keyword prompt (spaced strings would then have to be quoted), not sure, but I know it is a bit is a pain for my needs. At least it could have been an option.

 

I think I will just write a one liner int he Alfred script input to break apart $1 at spaces to create my args.

Link to comment

No, I am re-thinking how I approach it.

I just explained the way to handle this situation. If you want to ignore it, that's your prerogative. But any problems you have to solve as a result are really of your own making.

 

Linux world args passed to scripts are space delimited

That has nothing to do with Linux. You're talking about bash.

 

Not sure why Alfred decided to do it different.

Alfred isn't a shell from the 1980s, it's a GUI program from 2016. Consequently, it isn't built around an interaction model of users entering cryptic options and remembering to quote and escape input so everything doesn't die in flames.

 

it is a bit is a pain for my needs.

No, it isn't. All the pain is a result of your refusing to use Alfred in the correct way.

 

I think I will just write a one liner int he Alfred script input to break apart $1 at spaces to create my args.

 

You could do that. Of course $2, $3, $#, $@, getopts etc. won't work.

 

Or you could just use Alfred in the proper way, like I suggested, and everything would work perfectly.

Edited by deanishe
Link to comment

No, no, no. It's not my product, dude. Hell, all the worst (best, imo) rants on the forum against Alfred were written by me.

 

I'm basically the resident dick on the forum. OTOH, for my occasional-to-frequent bad attitude, I'm also one of the most experienced workflow developers and often right…

 

Sorry if you feel I went off in the deep end in reaction to your "Alfred's not like Linux: it's broken". That was a wee bit passive aggressive on your part, and tbh, passive isn't really my style. You should have seen the first draft of that post…

 

Seriously, Alfred isn't bash. If you won't accept that, you're only causing difficulty for yourself ('cos it ain't gonna change).

 

For what you want to do, you should do it the way I suggested. It works perfectly. Otherwise, you'll just be fighting with Alfred.

 

To back up my claim of shitting on Alfred, the Script box is a terrible editor. No highlighting, no line numbers (which you need to track down inevitable errors), and embedding all your code in info.plist ruins source control.

 

"What's changed? Info.plist!" Not super helpful…

 

As a rule, it's a much better idea to put your code in a separate file, anyway (for the above reasons), and treat the Script box like a command line. 

 

Put ./script.sh $1 (or ./script.sh "$1") in the Script box and the rest of your code in script.sh. It's the smart way to do it.

Edited by deanishe
Link to comment
  • 1 month later...
  • 1 year later...

I know this is a really old topic, but I just hit this issue too and it seems like OP didn't get an answer that fit the workflow he was trying to use (external script)

 

After stumbling through it for a while, I found a really cheesy solution:

 

vars=$1
var1=$(echo $1 | cut -d' ' -f1)
var2=$(echo $1 | cut -d' ' -f2)
var3=$(echo $1 | cut -d' ' -f3)

 

I can't explain why but the normal bash substring array approaches wouldn't work for me.. so.. cut to the rescue!

Link to comment
17 minutes ago, Buttetsu said:

I can't explain why but the normal bash substring array approaches wouldn't work for me

 

Because, apparently, you're using an External Script (which isn't what ilium007 was asking about). That's a whole different ballgame.

 

Splitting input on whitespace is a shell thing. If you're calling a script via External Script, it's run directly, not via a shell, so your entire query is passed as a single argument, whitespace be damned.

 

If you do as I explained above and treat the Script box as a shell (i.e. set language to /bin/bash or /bin/zsh), then an unquoted $1/{query} is split into multiple arguments on whitespace.

 

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...