How to Run a Shell Command When a File Is Added (Windows and Mac)
Run a shell command or script automatically when a file lands in a folder — on Windows and Mac. No Task Scheduler, no cron, no AppleScript. Here's how.
Running a command when a file appears in a folder used to mean Task Scheduler on Windows, cron or AppleScript on Mac, or Hazel if you were already on a Mac. File Arbor does it with a rule: pick the folder, match the files, choose Run command, and your script runs once per matching file — the same way on Windows and macOS. It is a Pro feature, added in version 1.1.0.
This guide shows how to set it up, the variables you get, how to test a command before trusting it, and a few recipes worth stealing.
Why this is harder than it should be
The need is simple: "when a file shows up here, do something to it." The tooling usually is not.
On macOS, Hazel has run shell scripts as a rule action for years. It is excellent — and Mac only. If you are on Windows, Hazel is not an option and never will be.
The built-in routes are clunky. Windows Task Scheduler can run a batch file on a timer, but it watches the clock, not the folder, and you write the matching logic yourself in forfiles or PowerShell. On macOS, Folder Actions and cron work but mean wiring up AppleScript or shell glue and debugging it in the Console. None of these give you a list of which files were processed or what each command printed.
What most people actually want is a rule: match a file, run a command, see what happened. That is the gap File Arbor's Run command action fills, on both platforms.
What the Run command action does
A File Arbor rule is an IF/THEN pair. The IF side matches files by extension, name pattern, full regex, size, or age. The THEN side is the action. Run command is one of the actions, alongside move, rename, move to Recycle Bin, and delete permanently.
When a file matches — on a manual run, on a schedule, or the moment it lands in a watched folder — File Arbor runs your command once for that file. On Windows it runs through the system shell, so batch syntax, PowerShell, and anything on your PATH work. On macOS it runs through the shell too, so your usual command-line tools are available. Same rule model, same editor, both platforms.
Run command is a Pro feature. If you are on the free plan, you can unlock it with a Pro license — a one-time purchase, backed by a 30-day refund guarantee.
How to run a command when a file is added
Here is the full setup. It takes about two minutes.
- Add the folder you want to watch. Click Add Folder and pick where files arrive —
Downloads, a project folder, a scanner output directory, whatever matches your workflow. - Create a rule and set the match conditions. Add a rule and define the IF side. Match by extension (
.md), a name pattern, a regex like^invoice_\d{4}\.pdf$, a size threshold, or an age. Only matching files trigger the command. - Choose Run command as the action. On the THEN side, select Run command and type your command. Use the variables below wherever you need the file's path or name.
- Test the command against a sample file. Click Test. File Arbor runs the command once on a sample and shows the exit code, the output, and the duration. Fix it here, before it ever runs unattended.
- Save the rule and enable Auto Mode. Save it, then turn on Auto Mode to run in real time as files land. You can also run rules manually or on a schedule.
That is the whole loop. No batch file, no scheduled task, no script files to maintain separately from the rule.
The variables you can use
Three variables are available inside a command:
{filePath}— the full path to the matched file{fileName}— just the file name, with extension{folder}— the folder the file is in
File Arbor quotes them for you, so paths with spaces work without you wrapping anything in quotes. You write {filePath}, not "{filePath}".
Test before you trust
A command that runs unattended is only useful if you know it works. Two things make that safe.
The Test button runs your command once against a sample file and reports the exit code, the output, and how long it took. You see exactly what the command does before you save the rule.
The Command runs panel records every real run — the command, the file, the exit code, and the full output. When something fails at 3 AM, you are not guessing. The output is sitting there when you check.
Real examples worth stealing
Auto-commit notes to a git repo. Drop a Markdown file into a notes folder and have it committed automatically.
- Watch:
C:\Projects\notes(or~/Projects/noteson Mac) - Match: extension is
.md - Command:
git -C {folder} add {fileName} && git -C {folder} commit -m "Add {fileName}"
Compress video the moment it lands. Re-encode screen recordings to save space.
- Match: extension is
.mov - Command:
ffmpeg -i {filePath} -vcodec libx265 -crf 28 {folder}/compressed-{fileName}
Upload finished exports off-site. Push a render to a backup server with rsync or scp.
- Match: name starts with
export_ - Command:
rsync {filePath} backup:/media/incoming/
Notify yourself when a specific file arrives. Trigger a desktop notification or a webhook so you know an invoice or report came in.
The pattern is always the same: match the file, run the tool you already use. File Arbor is the trigger and the file picker; your command does the work.
How this compares to Hazel's shell scripts
If you came here from a Hazel workflow, the mapping is direct. Hazel's "run shell script" action and File Arbor's Run command action both run a command per matched file with access to the file's path. The difference is reach: Hazel runs on macOS only, while File Arbor runs the same rule on Windows and Mac. For a deeper side-by-side, see File Arbor vs Hazel.
What File Arbor does not replicate is Hazel's macOS-specific scripting hooks — AppleScript and Spotlight-metadata conditions. If your automation depends on those, Hazel still has an edge on the Mac. For running commands and scripts against files, the two are on even ground.
Limits and safety
A few things to know before you wire up something important:
- One run per file. A matched file triggers the command once, not in a loop.
- 30-second timeout. Commands time out after 30 seconds by default, so a hung script cannot stall your other rules.
- Not in the Microsoft Store build. Store policy blocks apps from launching arbitrary commands, so the Store version ships without Run command. The direct download has it.
Start with one command
Pick one repetitive thing you do to files by hand — a commit, a compress, an upload — and turn it into a single rule. Download File Arbor and start on the free plan, or read what else shipped in 1.1.0. New to the app? The getting started guide sets up your first rule in about five minutes.
FAQ
Can File Arbor run shell scripts like Hazel?
Yes. File Arbor's Run command action runs any shell command or script once per matching file, with {filePath}, {fileName}, and {folder} variables. It covers the same ground as Hazel's shell script action — and it works on Windows, which Hazel does not. It is a Pro feature.
Does running commands on file events work on Windows?
Yes. File Arbor runs commands on both Windows and macOS. On Windows it runs through the system shell, so batch commands, PowerShell, and any tool on your PATH work. There is no need for Task Scheduler or a separate batch file.
Is the Run command action available in the free version?
No. Run command is a Pro feature — a one-time $24.99 purchase with a 30-day refund guarantee. The free plan still includes move, rename, and move-to-Recycle-Bin actions.
Why isn't Run command in the Microsoft Store version?
Microsoft Store policy restricts apps from launching arbitrary commands, so the Store build ships without the Run command action. Download File Arbor directly from filearbor.com to get it. Every other feature is identical between the two builds.
What happens if my command hangs or fails?
Commands time out after 30 seconds by default, so a stuck script cannot stall your rules. Every run is recorded in the Command runs panel with its exit code and full output, so a failure at 3 AM is waiting for you with the details when you check.
