-
Automate Folder Archiving on macOS with Raycast and 7zip
Tuesday October 14, 2025If you’re like me and frequently need to archive project folders to an external drive, you know how tedious the process can be: right-click, compress, wait, find the archive, move it to the external drive, rename if there’s a conflict… It’s a workflow that begs for automation.
Today, I’m going to show you how I built a custom Raycast script that compresses any folder with 7zip and automatically moves it to an external drive, all with a single keyboard shortcut.
What We’re Building
A Raycast script command that:
- Takes whatever folder you have selected in Finder
- Compresses it using 7zip (better compression than macOS’s built-in zip)
- Moves it directly to a specified folder on your external drive
- Automatically handles version numbering if the archive already exists
- Provides clear error messages if something goes wrong
No more manual copying. No more filename conflicts. Just select, trigger, and done.
Prerequisites
Before we start, you’ll need:
- Raycast - Download from raycast.com if you haven’t already
- 7zip - Install via Homebrew:
brew install p7zip- An external drive - Obviously, but make sure you know its mount path
The Problem with the Built-in Approach
Initially, I thought: “Can’t I just have Raycast pass the selected folder path as an argument?”
The answer is technically yes, but it’s clunky. Raycast would prompt you for the folder path every time, which means you’d need to:
- Copy the folder path
- Trigger the Raycast command
- Paste the path
- Hit enter
That’s not automation—that’s just extra steps with good intentions.
The Solution: AppleScript Integration
The key insight was using AppleScript to grab the currently selected item from Finder. This way, the workflow becomes:
- Select a folder in Finder
- Trigger the Raycast command (I use
Cmd+Shift+7) - Watch it compress and move automatically
No input required. No path copying. Just pure automation bliss.
Building the Script
Here’s the complete script with all the error handling we need:
#!/bin/bash # Required parameters: # @raycast.schemaVersion 1 # @raycast.title Compress Selected to External Drive # @raycast.mode fullOutput # Optional parameters: # @raycast.icon 📦 # @raycast.needsConfirmation false # Documentation: # @raycast.description Compress selected Finder folder with 7zip and move to external drive # [@raycast.author](http://raycast.author) Your Name EXTERNAL_DRIVE="/Volumes/YourDrive/ArchiveFolder" # Get the selected item from Finder FOLDER_PATH=$(osascript -e 'tell application "Finder" to set selectedItems to selection if (count of selectedItems) is 0 then return "" else return POSIX path of (item 1 of selectedItems as alias) end if') # Check if anything is selected if [ -z "$FOLDER_PATH" ]; then echo "❌ Error: No item selected in Finder" echo "Please select a folder in Finder and try again" exit 1 fi # Trim whitespace FOLDER_PATH=$(echo "$FOLDER_PATH" | xargs) # Check if path exists if [ ! -e "$FOLDER_PATH" ]; then echo "❌ Error: Path does not exist: $FOLDER_PATH" exit 1 fi # Check if path is a directory if [ ! -d "$FOLDER_PATH" ]; then echo "❌ Error: Selected item is not a folder: $FOLDER_PATH" exit 1 fi # Check if 7z is installed if ! command -v 7z &> /dev/null; then echo "❌ Error: 7z not found. Install with: brew install p7zip" exit 1 fi # Check if external drive is mounted if [ ! -d "$EXTERNAL_DRIVE" ]; then echo "❌ Error: External drive not found at: $EXTERNAL_DRIVE" echo "Make sure the drive is connected and mounted" exit 1 fi # Create archive name from folder name BASE_NAME="$(basename "$FOLDER_PATH")" ARCHIVE_NAME="${BASE_NAME}.7z" OUTPUT_PATH="$EXTERNAL_DRIVE/$ARCHIVE_NAME" # Check if archive already exists and find next available version number if [ -f "$OUTPUT_PATH" ]; then echo "⚠️ Archive already exists, creating versioned copy..." VERSION=2 while [ -f "$EXTERNAL_DRIVE/${BASE_NAME}_v${VERSION}.7z" ]; do VERSION=$((VERSION + 1)) done ARCHIVE_NAME="${BASE_NAME}_v${VERSION}.7z" OUTPUT_PATH="$EXTERNAL_DRIVE/$ARCHIVE_NAME" echo "📝 Using version number: v${VERSION}" echo "" fi echo "🗜️ Compressing: $(basename "$FOLDER_PATH")" echo "📍 Destination: $OUTPUT_PATH" echo "" # Compress with 7zip if 7z a "$OUTPUT_PATH" "$FOLDER_PATH"; then echo "" echo "✅ Successfully compressed and moved to external drive" echo "📦 Archive: $ARCHIVE_NAME" echo "📊 Size: $(du -h "$OUTPUT_PATH" | cut -f1)" else echo "" echo "❌ Error: Compression failed" exit 1 fiKey Features Explained
1. Finder Integration
The AppleScript snippet grabs whatever you have selected in Finder:
FOLDER_PATH=$(osascript -e 'tell application "Finder" to set selectedItems to selection if (count of selectedItems) is 0 then return "" else return POSIX path of (item 1 of selectedItems as alias) end if')This returns a POSIX path (like
/Users/yourname/Documents/project) that we can use with standard bash commands.2. Comprehensive Error Checking
The script validates everything before attempting compression:
- Is anything selected?
- Does the path exist?
- Is it actually a directory?
- Is 7zip installed?
- Is the external drive connected?
Each check provides a helpful error message so you know exactly what went wrong.
3. Automatic Version Numbering
This was a crucial addition. If
project.7zalready exists, the script will automatically createproject_v2.7z. If that exists, it’ll createproject_v3.7z, and so on:if [ -f "$OUTPUT_PATH" ]; then VERSION=2 while [ -f "$EXTERNAL_DRIVE/${BASE_NAME}_v${VERSION}.7z" ]; do VERSION=$((VERSION + 1)) done ARCHIVE_NAME="${BASE_NAME}_v${VERSION}.7z" OUTPUT_PATH="$EXTERNAL_DRIVE/$ARCHIVE_NAME" fiNo more manual renaming. No more overwriting precious backups.
4. Progress Feedback
Using
@raycast.mode fullOutputmeans you see everything that’s happening:- Which folder is being compressed
- Where it’s going
- The final archive size
This transparency is important when you’re archiving large projects that might take a few minutes.
Setting It Up
- Find your external drive path:
ls /Volumes/Look for your drive name, then determine where you want archives saved. For example:
/Volumes/Expansion/WebProjectsArchive-
Create the script:
- Open Raycast Settings → Extensions → Script Commands
- Click “Create Script Command”
- Paste the script above
- Update the
EXTERNAL_DRIVEvariable with your path - Save it (like
~/Documents/Raycast/Scripts/or~/.local/raycast)
-
Make it executable:
chmod +x ~/.local/raycast/compress-to-external.sh- Assign a hotkey (optional but recommended):
- In Raycast, search for your script
- Press
Cmd+Kand select “Add Hotkey” - I use
Cmd+Shift+7for “Archive”
Using It
Now the workflow is beautifully simple:
- Open Finder
- Select a folder
- Hit your hotkey (or trigger via Raycast search)
- Watch the magic happen
The script will show you the compression progress and let you know when it’s done, including the final archive size.
Why 7zip Over Built-in Compression?
macOS has built-in zip compression, so why bother with 7zip? A few reasons:
- Better compression ratios - 7zip typically achieves 30-70% better compression than zip
- Cross-platform - .7z files are widely supported on Windows and Linux
- More options - If you want to add encryption or split archives later, 7zip supports it
- Speed - 7zip can be faster for large files
For project archives that might contain thousands of files and dependencies, these advantages add up quickly.
Potential Improvements
This script works great for my needs, but here are some ideas for enhancement:
- Multiple drive support - Let the user select from available drives
- Compression level options - Add arguments for maximum vs. fast compression
- Notification on completion - Use macOS notifications for long-running compressions
- Delete original option - Add a flag to remove the source folder after successful archiving
- Batch processing - Handle multiple selected folders
Troubleshooting
“7z not found” error:
brew install p7zip“External drive not found” error: Make sure your drive is connected and the path in
EXTERNAL_DRIVEmatches exactly. Check with:ls -la /Volumes/YourDrive/YourFolderScript doesn’t appear in Raycast: Refresh the script directory in Raycast Settings → Extensions → Script Commands → Reload All Scripts
Permission denied: Make sure the script is executable:
chmod +x your-script.shConclusion
This Raycast script has saved me countless hours of manual file management. What used to be a multi-step process involving right-clicks, waiting, dragging, and renaming is now a single keyboard shortcut.
The beauty of Raycast’s script commands is that they’re just bash scripts with some metadata. If you know bash, you can automate almost anything on your Mac. This particular script demonstrates several useful patterns:
- Integrating with Finder via AppleScript
- Robust error handling
- Automatic file versioning
- User-friendly progress feedback
I encourage you to take this script and adapt it to your own workflow. Maybe you want to compress to Dropbox instead of an external drive. Maybe you want to add a timestamp to the filename. The flexibility is there, you just need to modify a few lines.
Happy automating!
Have questions or improvements? Feel free to reach out. If you build something cool with this pattern, I’d love to hear about it!
-
Programming
The Password Paradox: When Security Becomes Absurdity
Monday August 4, 2025I created an account on VRBO today and was shocked by their password policy. A password with over 30 characters was flagged as “weak” simply because it didn’t contain special characters. We can do better than this.
This is the current state of digital security: passwords so complex that humans can’t remember them, pushing us all toward password managers (which, let’s be honest, we should be using). But here’s the thing - while there are some standards and best practices for password security, implementation is wildly inconsistent. Each business decides how much they want to enforce “good” password policies, and even when they try to follow security methodologies, the execution is all over the map.
You end up with systems that reject genuinely strong passwords while accepting demonstrably weak ones, all because someone’s algorithm prioritizes symbols over entropy.
It’s security theater at its finest.
FREE THE EMAILS AT MY blurgl blog
-
Monday August 4, 2025
What you should start saying in Standup now
-
Last Weekend
🚨 Good Vibes Check! ✅
Friday July 4, 2025Reply with something Positive
-
Friday July 4, 2025
from the, seat at the table.



-
Thoughts
Wednesday July 2, 2025Reply with something Positive
-
Tuesday July 1, 2025
This just in. Live from Dysmyopia news, Here with updates from the world eye
-
Monday June 30, 2025
Here’s my recently added playlist on Apple Music 👀 music.apple.com/us/playli…
-
Monday June 30, 2025
(⌐ ͡■ ͜ʖ ͡■), dysmyopia—the dystopian hellscape vision of a world as seen by a short-sighted man.
-
Thoughts
Monday June 30, 2025It could be worse … is WAY BETTER than I can’t decide.
No wait, never mind … is WAY WORSE than I can’t decide.
because some days I swap the Better with the Worse,
and then nothing get’s done.I showed up, I gave a shit, For better or worse, Nirvana - Nevermind.
-
Programming
So the Gemini CLI...
Thursday June 26, 2025Two minor gripes with the Gemini CLI tool. I know, I know … it just came out.
-
There’s no init command to automatically get it to generate its context file. I asked it to do it, and it created an empty file, and then I had to follow up with a second prompt to get it to update the file with helpful information. I’m never going to use that until it’s easier.
-
I ran a few prompts, and it automatically switched to the flash model, and there’s no way to control what model it uses. Like maybe I’m okay with a bit slower responses if it means I can use the pro-model. I’d like the ability to be able to control this, and there doesn’t seem to be a way to switch between the models.
-
-
Thoughts
Wednesday June 25, 2025Watching Delicious in Dungeon and now I want a Dungeon Taco.
-
Wednesday June 25, 2025
I built a BlueSky Bot in 6 hours last week. I promise for good reasons.
TELL THE BOT THEY’RE DOING SUCH A GOOD JOB
It runs a query, does some analytics, then gives a progress update to socials.
-
Productivity
Wednesday June 25, 2025Threads was perfect cause last year …
so yea;
I’m back to blogging. I need to build my own custom Microblog theme, though.
Go to my Website to see the silly Canva video I made instead of configuring a Debian Server with Ansible using a tool that makes using Docker Swarm more manageable.
-
Programming
Tuesday June 10, 2025Before: 🔴 47 Dependabot PRs clogging my repo
After: 🟢 3 meaningful updates per week
The secret? One .github/dependabot.yml config to ignore patch updates while keeping security fixes.
Sometimes the best feature is the one that does less work 😌 #Productivity #GitHub #LessIsMore #JavaScript
-
Programming
Tuesday June 10, 2025Claude Code is awesome. Junie is awesome. I want to try Claude Code GitHub Actions but its not included in the Max Plan. What Agents have been working well for you? #javascript #dev #webdev #fullstack
-
Programming
Sunday June 8, 2025Happy 30th Birthday to PHP! To celebrate, I updated my CodeIgniter project to the latest version, refactored a bunch of stuff. I added a reference implementation of Vue to it. Claude helped. 🎉
-
Friday June 6, 2025
The coffee didn’t help #friday #help #sendnaps
-
Thursday June 5, 2025
GitHub API Limits logan.smmall.cloud/MTc0OTE2M…
-
AI
Saturday May 17, 2025Bet #GuessThatPrompt




-
Thursday May 15, 2025
Really liking Doom: The Dark Ages. The movement and the combat feel very fluid. The shield charge is satisfyingly good. It’s getting great scores on the Reviews.
-
Wednesday May 14, 2025
What are the robots gonna do… when they start keeping a journal? 🤖 Probably complain about their humans. 🤔 #RobotJournal
-
Tuesday May 13, 2025
I like to live dangerously and listen to that Sleep playlist at work. #TimeToFeed
-
Thursday May 8, 2025
I wish I would have prioritized my art more before the Tariffs and bought a Fujifilm X100VI. OH WELL >:(
-
Gaming
Anyone playing Elden Ring on Steam Deck??
Thursday May 8, 2025I have GeForce Now, two Macs, an Xbox and a Steam Deck. The two games I would play if I had a Gaming Computer: Elden Ring on Steam. Minecraft Bedrock on macOS or GFN. 😮💨 Does anyone know if Elden Ring Nightreign will be Crossplay? 😬