Jono Posted March 3, 2020 Share Posted March 3, 2020 (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 🙂 Edited March 3, 2020 by Jono Link to comment
deanishe Posted March 3, 2020 Share Posted March 3, 2020 (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 March 3, 2020 by deanishe Link to comment
vitor Posted March 3, 2020 Share Posted March 3, 2020 (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 March 3, 2020 by vitor Jono 1 Link to comment
Jono Posted March 3, 2020 Author Share Posted March 3, 2020 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
Jono Posted March 3, 2020 Author Share Posted March 3, 2020 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
deanishe Posted March 4, 2020 Share Posted March 4, 2020 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
Jono Posted March 4, 2020 Author Share Posted March 4, 2020 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
deanishe Posted March 4, 2020 Share Posted March 4, 2020 {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. Jono 1 Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now