Bernard Harte

Q: Automator: use variable & selected files as parameters for shell

I rarely use Automator, but it's useful for creating services.

 

I have a shell script that tags files, and in a service it iterates over selected files in Finder.

 

What I can't get my head around is how to ask the user for the tag to be applied (either as a literal or select from list) and then pass this as well as the file list to the shell as a parameter.

MacBook Pro (13-inch Late 2011), OS X El Capitan (10.11.3)

Posted on Feb 10, 2016 4:38 AM

Close

Q: Automator: use variable & selected files as parameters for shell

  • All replies
  • Helpful answers

  • by Tony T1,

    Tony T1 Tony T1 Feb 10, 2016 5:33 AM in response to Bernard Harte
    Level 6 (9,232 points)
    Mac OS X
    Feb 10, 2016 5:33 AM in response to Bernard Harte

    Are you speaking about text tags?

    You can use Ask for Text, then Set Variable, then before the Run Shell Script, Get Variable.  If this is the only variable passed, then it will be "$1"

    If you click the [Results] in the action before the Run Shell Script, you can see the order of the variables being passed:

     

    Screen Shot 2016-02-10 at 8.28.45 AM.png

     

    Note: $1 should be quoted: echo "$1"

  • by Tony T1,

    Tony T1 Tony T1 Feb 10, 2016 5:56 AM in response to Bernard Harte
    Level 6 (9,232 points)
    Mac OS X
    Feb 10, 2016 5:56 AM in response to Bernard Harte

    For a choose from list, you can use Run Applescript.

    [Note: return input is changed to: return selectedIssue as text

     

    Screen Shot 2016-02-10 at 8.56.22 AM.png

  • by Bernard Harte,

    Bernard Harte Bernard Harte Feb 10, 2016 5:59 AM in response to Tony T1
    Level 4 (3,309 points)
    iPhone
    Feb 10, 2016 5:59 AM in response to Tony T1

    Thanks for responding.

     

    Yes they are text tags.

     

    I understand how that works for one or more arguments to be passed to the shell, but if I also want to pass in the [selected] file list how do I do that?  (It seems that stdin|as arguments are mutually exclusive.)  My script flow control is a while read f ... do loop, which I am assuming - perhaps wrongly - is what I need to do the file iteration.

  • by Tony T1,Helpful

    Tony T1 Tony T1 Feb 10, 2016 8:14 AM in response to Bernard Harte
    Level 6 (9,232 points)
    Mac OS X
    Feb 10, 2016 8:14 AM in response to Bernard Harte

    If you pass the text before the files, I believe that its item 1 (or 0 really) in the array passed to the Run Shell Script, and the files will be in position 1 to the end. (you can check this in the [Results] window)

     

    So, first calc the number of items in the array, so that you can later reference them:

    for f in "$@"

    do

      file[$count]="$f"

      let count++

    done

     

    so the text should be in: file[0] and can be referenced as: echo ${file[0]}

     

    We can loop through the files as follows (starting with the first file in position 1 (the Text is in position 0):

     

    j=1

    while [ $j -le $count ]

    do

      echo Text is "${file[0]}" and File is "${file[j]}" >> ~/Desktop/tt.txt

      let j++

    done

     

    So, the completed script is:

     

     

    count=0

    for f in "$@"

    do

      file[$count]="$f"

      let count++

    done

     

     

    j=1

    while [ $j -le $count ]

    do

      echo Text is "${file[0]}" and File is "${file[j]}"

      let j++

    done

     

     

    Now just change

         echo Text is "${file[0]}" and File is "${file[j]}"

    to the command to add the Text to the File

     

     

    Screen Shot 2016-02-10 at 9.57.33 AM.png

  • by Tony T1,Solvedanswer

    Tony T1 Tony T1 Feb 10, 2016 7:24 AM in response to Bernard Harte
    Level 6 (9,232 points)
    Mac OS X
    Feb 10, 2016 7:24 AM in response to Bernard Harte

    Just tested and looks like the Text is the last item.

    Also, my counting was off.

     

    This script should work:

     

    count=0

    for f in "$@"

    do

      file[$count]="$f"

      let count++

    done

     

    let count--

    j=0

    while [ $j -lt $count ]

    do

      echo Text is "${file[$count]}" and File is "${file[j]}"

      let j++

    done

     

    Here's the Automator Workflow I tested with:

     

    Screen Shot 2016-02-10 at 10.22.51 AM.png

    Screen Shot 2016-02-10 at 10.23.04 AM.png

  • by Bernard Harte,

    Bernard Harte Bernard Harte Feb 10, 2016 7:28 AM in response to Tony T1
    Level 4 (3,309 points)
    iPhone
    Feb 10, 2016 7:28 AM in response to Tony T1

    I can see the principle of this, but I am still sketchy about the Automator steps proceeding the Run AppleScript: how do I 'pass the text before the files'?

     

    Could you show me the whole Automator workflow please?

  • by Bernard Harte,

    Bernard Harte Bernard Harte Feb 10, 2016 7:38 AM in response to Bernard Harte
    Level 4 (3,309 points)
    iPhone
    Feb 10, 2016 7:38 AM in response to Bernard Harte

    Sorry, I am getting a bit closer now:

     

    I ask for the tag text, save it to a var.  Then I retrieve the var, then Get Selected Finder Items and pass this into the Run Shell Script.  (I had forgotten about the way that Automator chains together variables as they drop down the workflow.)

     

    There's only one problem (before I try and put my own script to work): However many files I have selected in the Finder, it seems that only one is getting to the Shell Script.  (They appear in the preceding step's Results.)

  • by Tony T1,Helpful

    Tony T1 Tony T1 Feb 10, 2016 8:15 AM in response to Bernard Harte
    Level 6 (9,232 points)
    Mac OS X
    Feb 10, 2016 8:15 AM in response to Bernard Harte

    See my last post below (Re: Automator: use variable & selected files as parameters for shell).

    The position of the Text Comment in the arrary is dependent upon when the variable is got.

    Also you can redirect echo to a file to see what's happening before you run on the files:

         echo Text is "${file[$count]}" and File is "${file[j]}" >> ~/Desktop/text.txt

    As this appends to the file (>>), delete between runs.

  • by Bernard Harte,

    Bernard Harte Bernard Harte Feb 10, 2016 8:17 AM in response to Tony T1
    Level 4 (3,309 points)
    iPhone
    Feb 10, 2016 8:17 AM in response to Tony T1

    Thanks.  That all makes sense now.

     

    I was getting hung up on the order of retrieving the tag-containing variable and getting the selection list from Finder.  If they're the other way around, only the file list gets passed as an argument.

     

    Now to try and get it to work with my full script!

  • by Bernard Harte,

    Bernard Harte Bernard Harte Feb 10, 2016 9:20 AM in response to Tony T1
    Level 4 (3,309 points)
    iPhone
    Feb 10, 2016 9:20 AM in response to Tony T1

    You may be interested that I modified the shell wrapper to grab the tag text and file list into vars upfront. I also trimmed the last item off the argument array once I had it safely in a var:

     

    #get the tag text from the last item of the argument array

    eval tag_text=\${$#}

    echo $tag_text

     

    #put the argument array into a local array var and trim last item

    file_list=("$@")

    unset file_list[${#file_list[@]}-1]

     

    #loop over the local array var

    for infile in "${file_list[@]}"; do

        echo $infile

    done

     

    I do have one more question: When I run all this as a service, it behaves as expected, but the dialog asking for the tag text doesn't have focus (so I need to click on it).  I know I have come across this before, but I can't find the solution.  I am sure that someone who uses Automator all the time will know


    Scratch that - needed to 'activate' at the top.  Thanks again for your help.

  • by Tony T1,

    Tony T1 Tony T1 Feb 10, 2016 9:31 AM in response to Bernard Harte
    Level 6 (9,232 points)
    Mac OS X
    Feb 10, 2016 9:31 AM in response to Bernard Harte

    Looks good!