Jump to content
Jono

Help with shell script workflow

Recommended Posts

Posted (edited)

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

Share this post


Link to post
Posted (edited)

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

Share this post


Link to post
Posted (edited)
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

Share this post


Link to post

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?

Share this post


Link to post
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! 🙂

Share this post


Link to post
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}"

Share this post


Link to post
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) 😐

Share this post


Link to post

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

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...