I'm porting an Automator action to Shortcuts and I'm having a bit of trouble. Here's my Automator action:

oxipng Quick Action in Big Sur's Automator

The snippet of zsh inside is:

for f in "$@"
    /usr/local/bin/oxipng -pD -o max "$f"

This Automator action lets me select a bunch of PNG files in Finder, right-click on them, choose Services → oxipng -pD -o max, and after a while, the files will be smaller thanks to oxipng.

However, when I try to port it to Shortcuts, I'm a bit stuck. Here's what I have so far, in a Shortcut with a less nerdy name, an adjusted path to oxipng, and some debugging printfs:

oxipng with libdeflate Shortcut

As an aside, the Shortcut Input to the Run Shell Script action is Type: File, Get: File Path. By default, names passed in don't have the full file path or file extensions.

When I run the Shortcut with only one image selected, everything runs just as it used to. However, if I select a bunch of files, I'm prompted to choose only one of them. The prompt looks like this:

Shortcut prompting me for paths

How can I get my Shortcut to process all the files that I've passed to it?

  • It works for me: the only difference I can see is that i've used "Ask for Files" if there's no input.
    – benwiggy
    Dec 4, 2021 at 21:50

2 Answers 2


To avoid processing a list of file paths in your shell script just loop over the input with Repeat with Each and pass each file path as the script argument with a Shortcuts variable. Quote it to keep spaces and other special characters present in the path. A screenshot of Shortcuts looping over multiple files

  • This is much, much cleaner than the accepted answer. I used it for a slightly different Shortcut (-pZ -o max) where each item is expected to take a long time and I want one notification per item processed.
    – adiabatic
    Dec 27, 2021 at 6:32

Ran into the same issue while trying to port some Automator scripts to Shortcuts. So frustrating. I really hope there's a better approach than the workaround I came up with.

Here's what ended up working for me:

1. Start with the "Combine Text" action

2. Right click on "Text List," hover over "Select Variable" and choose "Shortcut Input"

3. Left click on "Shortcut Input" and select "File Path". Make sure "With New Lines" is selected

This will combine the input file paths with newlines.

4. Convert the newline-separated filename input into an array and iterate over it.

I tried a few other ways of combining / replacing the file paths prior to the shell script (e.g. sending them in as quoted strings separated by a space -- "file 1" "file 2") to see if I could make "$@" work as it normally does, but I gave up after a while. No matter what I did "$1" looked just like "$@". So I ended up with something custom.

Shell script

Here's the shell script for easy copy/paste (should work on bash and zsh by just modifying the index of FILES in the dirname command for bash as noted in the comments):

# Expects a file path or newline-separated list of file paths

# Change Internal Field Separator (IFS) to newline,
# convert the input file paths(s) into an array (uses IFS),
# then revert IFS
FILES=($(echo $@))

# If needed, e.g. to created a new sub-directory for output, 
# cd to the files' directory using the first item in the array
# (change index to 0 if bash -- zsh arrays start at 1)
cd "$(dirname "${FILES[1]}")"
# mkdir -p ./output # Example: create a directory for output

# Iterate over the files in the array
for FILE in "${FILES[@]}"; do
  # Do stuff with $FILE here

All together

Make sure in the Shell Script to choose "Input: Combined Text" and "Pass Input: as arguments"

  • 1
    You can use Shortcuts variables inside the script text. Ctrl-click the text field and insert a variable then use it as a string value.
    – Nikita
    Dec 20, 2021 at 16:35
  • Yes, it seems all loop logic is in shell script unnecessarily. This is not optimal solution at all then.
    – Roman
    Jan 14 at 11:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .