Skip to content
MacScout

Placeholders and environment

How MacScout fills in paths, where commands run, and what the shell sees.

Placeholders

Before a command runs, MacScout replaces its placeholders with paths. Take a file /Users/alex/Pictures/Beach Day.jpg, with /Users/alex/Pictures open in the active pane and /Users/alex/Desktop in the other one:

PlaceholderBecomesThe command runs
{file}'/Users/alex/Pictures/Beach Day.jpg'once per item
{dir}'/Users/alex/Pictures', the folder that contains the itemonce per item
{name}'Beach Day.jpg'once per item
{basename}'Beach Day', the name without its extensiononce per item
{ext}'jpg', without the dotonce per item
{files}every selected item, each quoted, separated by spacesonce
{folder}'/Users/alex/Pictures', the folder open in the active paneonce
{otherPane}'/Users/alex/Desktop', the folder open in the other paneonce

Once, or once per item

If a command contains {file}, {dir}, {name}, {basename} or {ext}, MacScout runs it once for every selected item, one after the other. If one run fails, the remaining items are skipped.

Without those placeholders, the command runs once, however many items are selected. {files} works in both kinds of command and always contains the whole selection.

Quoting

MacScout wraps every value in single quotes, so spaces, quotes and other special characters in file names can't break the command. Don't add quotes of your own:

// Right
"command": "cwebp {file} -o {dir}/{basename}.webp"

// Wrong: the extra quotes become part of the path
"command": "cwebp \"{file}\" -o \"{dir}/{basename}.webp\""

In the first command, {dir}/{basename}.webp turns into '/Users/alex/Pictures'/'Beach Day'.webp. The shell joins the quoted parts and the text between them into a single argument, /Users/alex/Pictures/Beach Day.webp.

With nothing selected

An action with "background": true also runs when nothing is selected, for example when you right-click empty space in a folder. It then works on the open folder: {file} and {files} are that folder, {dir} is its parent, and {name} is its name.

Two panes

{otherPane} is the folder in the other pane while a tab shows two panes (⌘3). With a single pane it is empty (''). Commands that write into the other pane should check for that; Recipes shows how.

The working directory

A command starts in:

  1. the selected folder, if exactly one folder is selected,
  2. otherwise the folder that contains the selection, if all selected items are in the same folder,
  3. otherwise the folder open in the active pane.

With nothing selected, it starts in the open folder. Search results can come from several folders, so use {dir} when a command needs the folder of each item.

Environment variables

Every command also gets these variables, except commands with "output": "terminal", which run in a new terminal window:

VariableContains
MACSCOUT_FILESThe paths of the selected items, one per line. With nothing selected, the open folder.
MACSCOUT_FOLDERThe folder open in the active pane
MACSCOUT_OTHER_PANEThe folder open in the other pane, or an empty string

They are handy in your own scripts, which can read the selection without dealing with quoting:

~/bin/sizes
#!/bin/sh
# Prints the size of every selected item.
printf '%s\n' "$MACSCOUT_FILES" | while IFS= read -r item; do
  du -sh "$item"
done
{ "title": "Sizes", "command": "~/bin/sizes", "output": "show" }

Remember to make the script executable with chmod +x ~/bin/sizes. The App Store version can't start a script from your home folder, so there, let the shell read it: "command": "sh ~/bin/sizes".

The shell

command runs in your login shell. MacScout starts it like zsh -l -c "<command>", or with the shell from the shell setting. The folder of the command is set as described above.

A login shell reads your profile, so tools installed with Homebrew are found. The App Store version can't start them, though, see Developer tools. It doesn't read ~/.zshrc, though, because that file is only for interactive shells. zsh reads ~/.zshenv, ~/.zprofile and ~/.zlogin, after the system-wide versions in /etc.

If a command works in Terminal but MacScout reports "command not found", the tool is probably set up in ~/.zshrc. nvm, for example, adds itself there. You can:

  • move the lines that set up PATH from ~/.zshrc to ~/.zprofile, or
  • use the full path to the tool in your command. which ffmpeg in Terminal tells you what it is.

If you use bash, a login shell reads ~/.bash_profile (or ~/.profile) and not ~/.bashrc.

In the App Store version, some tools in /usr/bin, like git, make and python3, stop with "xcrun: error: cannot be used within an App Sandbox". Developer tools explains why and what to use instead.

Without a shell: executable and arguments

Instead of a command, an action can name a program and its arguments. MacScout then starts the program directly:

{
  "title": "Extended Attributes",
  "executable": "/usr/bin/xattr",
  "arguments": ["-l", "{files}"],
  "output": "show"
}

This works differently from command:

  • There is no shell. Pipes, redirects, variables and ~ in arguments don't work. A ~ at the start of executable itself is expanded.
  • Give the full path. Without a shell, MacScout can't look the program up in your PATH. /usr/bin/xattr works, xattr doesn't.
  • No quoting. Placeholders are replaced with the plain path. Each entry in arguments is passed as exactly one argument, even if it contains spaces.
  • {files} must be an argument on its own. "{files}" turns into one argument per selected item. Inside a longer argument, like "--input={files}", it isn't replaced.
  • The program runs once. {file}, {dir}, {name}, {basename} and {ext} refer to the first selected item.
  • "output": "terminal" isn't supported. The program runs in the background, as with "none".

The working directory and the environment variables are the same as for command.

On this page