Jump to content

Help with shell script workflow


Recommended Posts

I don't know much at all about shell scripting, but I managed to cobble together a workflow that actually works.

theFile="{query}"

theImage=$(basename "${theFile}")
fileName="${theImage%.*}"
outputFile=$"$HOME/Desktop/$fileName.jpg"

sips -s format jpeg -s formatOptions 100 "${theFile}" --out "${outputFile}"
open -a ImageOptim "${outputFile}"

 

I'm using it as a File Action, so select a PNG image, run the workflow and it converts it to JPG, then runs it though ImageOptim.

 

This works when selecting single images. but doesn't work if I pass it multiple PNGs. In the File Action part of the workflow I checked 'Accept multiple files', so I'm guessing I need to alter the script to make it work? In the Run Script part of the workflow I tried it with 'running instances' set to Sequentially and then Concurrently, but that didn't make any difference.

 

Also, I wanted to show the name of the image in a notification. I tried {query} but that shows the full path to the original image, and also tried ${fileName} (and variations of it) but that didn't work either.

 

Any help would be appreciated 🙂

 

 

 

 

Screenshot 2020-03-03 at 9.43.52 am.jpg

Edited by Jono
Link to comment

Change your script to "with input as argv" (which tells Alfred to actually pass it multiple filepaths), and add a loop:

for theFile in $@; do
  theImage=$(basename "${theFile}")
  fileName="${theImage%.*}"
  outputFile=$"$HOME/Desktop/$fileName.jpg"
  sips -s format jpeg -s formatOptions 100 "${theFile}" --out "${outputFile}"
  open -a ImageOptim "${outputFile}"
done
Edited by deanishe
Link to comment
for theFile in $@; do

Make it

for theFile in "$@"; do

Or arguments may re-split on spaces. Even if Alfred takes that into account, it’s a good idea to do so anyway.

outputFile=$"$HOME/Desktop/$fileName.jpg"

What’s the first $ for? And use curly braces around variables, like you do in the rest of the script.


Also, I recommend you use the long form of flags in scripts (-s → --setProperty), as you’ll understand them better later on.

outputFile="${HOME}/Desktop/${fileName}.jpg"

Finally, note that with the current implementation you may be overwriting files, which you likely want to avoid. This version will append a random number to end of the file name if the file already exists.

for theFile in "${@}"; do
  fileName="$(basename "${theFile%.*}")"
  saveDir="${HOME}/Desktop"

  outputFile="$([[ -f "${saveDir}/${fileName}.jpg" ]] && echo "${saveDir}/${fileName}-${RANDOM}.jpg" || echo "${saveDir}/${fileName}.jpg")"

  sips --setProperty format jpeg --setProperty formatOptions 100 "${theFile}" --out "${outputFile}"
  open -a ImageOptim "${outputFile}"
done

 

Edited by vitor
Link to comment

Thanks, this works on images without a space in the filename, but not with spaces in the filename.

 

Could that be something to do with the line above it?

 

theFile="${1}"

 

Also, I wanted to show the name of the image in a notification. I tried {query} but that shows the full path to the original image, and also tried ${fileName} (and variations of it) but that didn't work either. How would I do that?

Link to comment
6 minutes ago, vitor said:

for theFile in $@; do

Make it


for theFile in "$@"; do

Or arguments may re-split on spaces. Even if Alfred takes that into account, it’s a good idea to do so anyway.


outputFile=$"$HOME/Desktop/$fileName.jpg"

What’s the first $ for? And use curly braces around variables; from all the places in the script, those are the most relevant.


Also, I recommend you use the long form of flags in scripts (s → --setProperty), as you’ll understand them better later on.


outputFile="${HOME}/Desktop/${fileName}.jpg"

Finally, note that with the current implementation you may be overwriting files, which you likely want to avoid.


for theFile in "${@}"; do
  fileName="$(basename "${theFile%.*}")"
  saveDir="${HOME}/Desktop"

  outputFile="$([[ -f "${saveDir}/${fileName}.jpg" ]] && echo "${saveDir}/${fileName}-${RANDOM}.jpg" || echo "${saveDir}/${fileName}.jpg")"

  sips --setProperty format jpeg --setProperty formatOptions 100 "${theFile}" --out "${outputFile}"
  open -a ImageOptim "${outputFile}"
done

 

 

That works, thanks a lot! 🙂

Link to comment
7 hours ago, Jono said:

I tried {query} but that shows the full path to the original image, and also tried ${fileName} (and variations of it) but that didn't work either. How would I do that?

 

Those variables only exist in your script. Use echo to send text to a notification: echo "${fileName}"

Link to comment
3 hours ago, deanishe said:

 

Those variables only exist in your script. Use echo to send text to a notification: echo "${fileName}"

 

Ah, right. Where should 'echo "${fileName}"' go in the script? At the end after 'done'? And I should still add {query} in the notification?

 

I've tried it in various places in the script, but it either shows the filename along with the full path of the input and output, or just shows the full path of the input and output (no filename on it's own) 😐

Link to comment

{query} in the Notification is replaced with whatever you echo from your script. So if you put echo in the loop, it'll show all the destination paths.


The simplest solution is probably to put echo -n "${fileName}" after done (the -n tells echo not to add a newline), and then select the "Last path component" option in the Notification's configuration.

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