前言:Automator与Shell脚本的协同力量
在黑苹果的日常使用中,系统维护、批量操作和重复性任务占据了大量时间。macOS自带的Automator工具提供了图形化的工作流编排能力,而Shell脚本则提供了精确的程序化控制。当两者结合使用时,能够构建出强大的自动化系统——从批量重命名文件到定期清理系统缓存,从一键配置开发环境到自动备份重要数据。本文将从Automator的基础操作到Shell脚本的高级技巧,全面讲解黑苹果环境下的深度自动化实战。
一、Automator工作流基础
1.1 Automator的工作流类型
Automator提供以下工作流类型:
- 工作流(Workflow):在Automator内运行的通用工作流
- 应用程序(Application):可独立运行的应用程序,接受拖放输入
- 快速操作(Quick Action):集成到右键菜单和Finder的工具栏
- 打印插件(Print Plugin):在打印对话框中可用
- 文件夹操作(Folder Action):当文件添加到指定文件夹时自动触发
- 日历提醒(Calendar Alarm):在日历事件触发时运行
- 图像捕获插件(Image Capture Plugin):在图像捕获应用中可用
对于黑苹果用户,最常用的是快速操作(右键菜单集成)和文件夹操作(自动处理新文件)。
1.2 创建第一个快速操作
以下是一个实用的快速操作——将选中的图片批量转换为WebP格式:
- 打开Automator → 新建 → 快速操作
- 设置"工作流程收到当前"为"图像文件",位于"Finder.app"
- 从左侧库中拖入"运行Shell脚本"动作
- 设置Shell为/bin/bash,传递输入为"作为自变量"
- 输入以下脚本:
#!/bin/bash
# 批量转换图片为WebP格式
# 需要先安装webp工具:brew install webp
for f in "$@"; do
# 获取文件扩展名和目录
dir="$(dirname "$f")"
base="$(basename "$f" | sed 's/\.[^.]*$//')"
# 转换为WebP,质量85%
cwebp -q 85 "$f" -o "${dir}/${base}.webp" 2>/dev/null
if [ $? -eq 0 ]; then
echo "转换成功: ${base}.webp"
else
echo "转换失败: $f"
fi
done
# 发送通知
osascript -e "display notification \"WebP转换完成\" with title \"Automator\""
保存为"转换为WebP"后,在Finder中右键点击图片文件即可看到该选项。
二、文件夹操作自动化
2.1 自动整理下载文件夹
创建一个文件夹操作,当新文件添加到Downloads文件夹时,自动按文件类型整理到子目录:
#!/bin/bash
# auto_organize_downloads.sh
# 附加到 ~/Downloads 文件夹的文件夹操作
DOWNLOADS="$HOME/Downloads"
# 定义文件类型分类
declare -A CATEGORIES
CATEGORIES["文档"]="pdf doc docx xls xlsx ppt pptx txt rtf odt"
CATEGORIES["图片"]="jpg jpeg png gif bmp svg webp ico tiff psd"
CATEGORIES["视频"]="mp4 mkv avi mov wmv flv webm m4v"
CATEGORIES["音频"]="mp3 wav flac aac ogg wma m4a"
CATEGORIES["压缩包"]="zip rar 7z tar gz bz2 xz dmg"
CATEGORIES["代码"]="py js ts html css json xml yaml yml sh bat"
CATEGORIES["安装包"]="pkg dmg app"
# 处理添加的文件
for f in "$@"; do
# 跳过目录和隐藏文件
[ -d "$f" ] && continue
basename "$(basename "$f")" | grep -q "^\." && continue
# 获取文件扩展名
ext="${f##*.}"
ext=$(echo "$ext" | tr '[:upper:]' '[:lower:]')
# 查找匹配的分类
target_dir=""
for category in "${!CATEGORIES[@]}"; do
if echo "${CATEGORIES[$category]}" | grep -qw "$ext"; then
target_dir="$DOWNLOADS/$category"
break
fi
done
# 如果没有匹配的分类,放入"其他"
[ -z "$target_dir" ] && target_dir="$DOWNLOADS/其他"
# 创建目标目录并移动文件
mkdir -p "$target_dir"
mv "$f" "$target_dir/"
echo "移动: $(basename "$f") → $target_dir/"
done
2.2 自动转换HEIC照片
黑苹果用户经常从iPhone接收HEIC格式照片,在部分应用中不兼容。创建自动转换的文件夹操作:
#!/bin/bash
# auto_convert_heic.sh
# 监控指定文件夹,自动将HEIC转换为JPEG
WATCH_DIR="$HOME/Pictures/HEIC_Inbox"
OUTPUT_DIR="$HOME/Pictures/JPEG_Output"
mkdir -p "$OUTPUT_DIR"
for f in "$@"; do
ext="${f##*.}"
if [ "$(echo "$ext" | tr '[:upper:]' '[:lower:]')" = "heic" ]; then
base="$(basename "$f" | sed 's/\.[^.]*$//')"
# 使用sips(macOS内置图片处理工具)转换
sips -s format jpeg -s formatOptions 95 "$f" --out "${OUTPUT_DIR}/${base}.jpg"
if [ $? -eq 0 ]; then
echo "转换成功: ${base}.jpg"
# 可选:转换成功后删除原文件
# rm "$f"
fi
fi
done
使用macOS内置的sips工具而非ImageMagick,无需额外安装依赖。
三、Shell脚本高级自动化
3.1 黑苹果系统维护脚本
以下是一键式的黑苹果系统维护脚本,涵盖常见维护任务:
#!/bin/bash
# hackintosh_maintenance.sh
# 黑苹果一键系统维护脚本
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 1. 清理系统缓存
clean_caches() {
log_info "清理系统缓存..."
# 清理用户缓存
du -sh ~/Library/Caches/ 2>/dev/null || true
find ~/Library/Caches/ -type f -mtime +30 -delete 2>/dev/null || true
log_info "已清理30天以上的用户缓存文件"
# 清理Xcode派生数据
if [ -d ~/Library/Developer/Xcode/DerivedData ]; then
du -sh ~/Library/Developer/Xcode/DerivedData/
rm -rf ~/Library/Developer/Xcode/DerivedData/*
log_info "已清理Xcode DerivedData"
fi
# 清理Homebrew缓存
if command -v brew &>/dev/null; then
brew cleanup --prune=30 -s 2>/dev/null || true
log_info "已清理Homebrew缓存"
fi
}
# 2. 修复磁盘权限
repair_permissions() {
log_info "验证启动盘..."
# 验证APFS卷宗
diskutil verifyVolume / 2>/dev/null || true
# 修复用户目录权限
diskutil resetUserPermissions / $(id -u) 2>/dev/null || true
log_info "已重置用户权限"
}
# 3. 清理系统日志
clean_logs() {
log_info "清理系统日志..."
# 删除30天前的系统日志
sudo find /private/var/log/ -type f -mtime +30 -delete 2>/dev/null || true
# 清理诊断报告
find ~/Library/Logs/DiagnosticReports/ -type f -mtime +30 -delete 2>/dev/null || true
find /Library/Logs/DiagnosticReports/ -type f -mtime +30 -delete 2>/dev/null || true
# 清理统一日志
sudo log erase --ttl 7 2>/dev/null || true
log_info "已清理过期日志"
}
# 4. 检查EFI分区
check_efi() {
log_info "检查EFI分区..."
# 查找EFI分区
EFI_PARTITION=$(diskutil list | grep EFI | head -1 | awk '{print $NF}')
if [ -n "$EFI_PARTITION" ]; then
log_info "EFI分区: /dev/$EFI_PARTITION"
# 检查EFI分区使用率
sudo diskutil mount $EFI_PARTITION 2>/dev/null || true
df -h /Volumes/EFI 2>/dev/null || true
else
log_warn "未找到EFI分区"
fi
}
# 5. 系统健康报告
health_report() {
log_info "====== 系统健康报告 ======"
# 内存使用
memory_pressure | head -3
# 磁盘使用
df -h / | tail -1
# S.M.A.R.T状态(如果安装了smartmontools)
if command -v smartctl &>/dev/null; then
DISK=$(diskutil info / | grep "Device Node" | awk '{print $NF}')
smartctl -H "$DISK" 2>/dev/null || true
fi
# 运行时间
uptime
# 最近Kernel Panic
RECENT_PANICS=$(ls -lt /Library/Logs/DiagnosticReports/*panic* 2>/dev/null | head -3)
if [ -n "$RECENT_PANICS" ]; then
log_warn "发现最近的Kernel Panic报告:"
echo "$RECENT_PANICS"
else
log_info "无最近Kernel Panic"
fi
}
# 执行所有维护任务
echo "========================================="
echo " 黑苹果系统维护脚本"
echo " $(date)"
echo "========================================="
health_report
clean_caches
clean_logs
repair_permissions
check_efi
echo ""
log_info "维护完成!"
3.2 OpenCore EFI自动备份脚本
#!/bin/bash
# oc_efi_backup.sh
# 自动备份OpenCore EFI分区
BACKUP_ROOT="$HOME/OC_Backups"
TIMESTAMP=$(date "+%Y%m%d_%H%M%S")
BACKUP_DIR="${BACKUP_ROOT}/EFI_${TIMESTAMP}"
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 查找并挂载EFI分区
EFI_DISK=$(diskutil list | grep EFI | head -1 | awk '{print $NF}')
if [ -z "$EFI_DISK" ]; then
echo "错误:未找到EFI分区"
exit 1
fi
echo "挂载EFI分区: /dev/$EFI_DISK"
sudo diskutil mount /dev/$EFI_DISK
# 复制EFI内容
EFI_PATH="/Volumes/EFI"
if [ -d "$EFI_PATH/EFI" ]; then
cp -R "$EFI_PATH/EFI" "$BACKUP_DIR/"
echo "备份完成: $BACKUP_DIR"
# 记录当前SMBIOS信息
ioreg -l | grep -i "serial-number" > "$BACKUP_DIR/smbios_info.txt" 2>/dev/null || true
# 记录config.plist哈希
shasum -a 256 "$BACKUP_DIR/EFI/OC/config.plist" > "$BACKUP_DIR/config_hash.txt"
else
echo "错误:EFI分区内容不存在"
fi
# 卸载EFI分区
sudo diskutil unmount /dev/$EFI_DISK
# 保留最近10个备份
cd "$BACKUP_ROOT"
ls -t | tail -n +11 | xargs rm -rf 2>/dev/null || true
echo "自动清理完成,保留最近10个备份"
3.3 开发环境一键部署脚本
#!/bin/bash
# dev_setup.sh
# 黑苹果开发环境一键部署
set -e
echo "====== 黑苹果开发环境部署 ======"
# 1. 安装Xcode命令行工具
if ! xcode-select -p &>/dev/null; then
echo "安装Xcode命令行工具..."
xcode-select --install
echo "请等待Xcode命令行工具安装完成后重新运行此脚本"
exit 0
fi
# 2. 安装Homebrew
if ! command -v brew &>/dev/null; then
echo "安装Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
# 3. 安装基础开发工具
echo "安装基础开发工具..."
brew install --formula \
git curl wget tree jq htop tmux \
python@3.12 node@22 go rust \
neovim ripgrep fd bat eza \
ffmpeg imagemagick
# 4. 安装常用应用
echo "安装常用应用..."
brew install --cask \
visual-studio-code iterm2 \
docker desktop slack discord
# 5. 配置Git
if [ ! -f ~/.gitconfig ]; then
echo "配置Git..."
read -p "Git用户名: " git_name
read -p "Git邮箱: " git_email
git config --global user.name "$git_name"
git config --global user.email "$git_email"
git config --global init.defaultBranch main
git config --global core.editor nvim
fi
# 6. 配置Shell
if [ ! -d ~/.oh-my-zsh ]; then
echo "安装Oh My Zsh..."
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
fi
# 7. 配置Python虚拟环境
pip3 install --user virtualenv poetry black isort mypy ruff
# 8. 配置Node.js
npm install -g typescript ts-node pnpm
echo ""
echo "====== 部署完成 ======"
echo "请重启终端以使所有配置生效"
四、Automator与Shell脚本深度集成
4.1 通过Automator创建右键菜单脚本
将Shell脚本封装为快速操作,添加到Finder右键菜单:
- 打开Automator → 新建"快速操作"
- 设置接收类型为"文件或文件夹",位于"Finder"
- 添加"运行Shell脚本"动作
- 编写处理逻辑
实用的快速操作示例——计算文件夹大小:
#!/bin/bash
# 在Finder右键菜单中显示选中文件夹的总大小
for f in "$@"; do
if [ -d "$f" ]; then
size=$(du -sh "$f" 2>/dev/null | awk '{print $1}')
osascript -e "display notification \"$(basename "$f"): $size\" with title \"文件夹大小\""
fi
done
4.2 通过launchd定时执行Shell脚本
将维护脚本配置为定时任务:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.yoozai.hackintosh-maintenance</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/hackintosh_maintenance.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/tmp/hackintosh_maintenance.log</string>
<key>StandardErrorPath</key>
<string>/tmp/hackintosh_maintenance_err.log</string>
</dict>
</plist>
# 安装launchd定时任务
cp com.yoozai.hackintosh-maintenance.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.yoozai.hackintosh-maintenance.plist
# 验证任务是否加载
launchctl list | grep yoozai
4.3 使用osascript实现跨应用自动化
osascript允许Shell脚本控制macOS应用程序,实现跨应用自动化:
#!/bin/bash
# morning_routine.sh
# 早晨工作准备自动化脚本
# 1. 调整显示器亮度到70%
osascript -e 'tell application "System Events" to key code 107' # 降低亮度
# 或使用brightnessctl(需要安装)
# 2. 打开常用应用
open -a "Safari"
open -a "Mail"
open -a "Slack"
open -a "Visual Studio Code"
# 3. 在Safari中打开常用标签页
osascript -e '
tell application "Safari"
activate
open location "https://github.com"
delay 1
tell application "System Events" to keystroke "t" using command down
open location "https://stackoverflow.com"
end tell'
# 4. 设置勿扰模式(macOS 12+)
osascript -e '
tell application "System Events"
tell process "ControlCenter"
-- 点击控制中心的勿扰模式按钮
end tell
end tell'
# 5. 播放欢迎提示音
afplay /System/Library/Sounds/Glass.aiff
# 6. 显示通知
osascript -e 'display notification "工作环境已准备就绪" with title "早晨准备" sound name "Glass"'
五、黑苹果特有的自动化场景
5.1 自动检测kext更新
#!/bin/bash
# check_kext_updates.sh
# 检查OpenCore kext是否有新版本
EFI_PATH="/Volumes/EFI/EFI/OC"
KEXT_DIR="$EFI_PATH/Kexts"
# 挂载EFI
sudo diskutil mount $(diskutil list | grep EFI | head -1 | awk '{print $NF}')
echo "====== Kext版本检查 ======"
# 检查Lilu
if [ -f "$KEXT_DIR/Lilu.kext/Contents/Info.plist" ]; then
local_version=$(plutil -extract CFBundleVersion xml1 -o - "$KEXT_DIR/Lilu.kext/Contents/Info.plist" | grep string | awk -F'[><]' '{print $3}')
echo "Lilu: 本地版本 $local_version"
fi
# 检查WhateverGreen
if [ -f "$KEXT_DIR/WhateverGreen.kext/Contents/Info.plist" ]; then
local_version=$(plutil -extract CFBundleVersion xml1 -o - "$KEXT_DIR/WhateverGreen.kext/Contents/Info.plist" | grep string | awk -F'[><]' '{print $3}')
echo "WhateverGreen: 本地版本 $local_version"
fi
# 检查AppleALC
if [ -f "$KEXT_DIR/AppleALC.kext/Contents/Info.plist" ]; then
local_version=$(plutil -extract CFBundleVersion xml1 -o - "$KEXT_DIR/AppleALC.kext/Contents/Info.plist" | grep string | awk -F'[><]' '{print $3}')
echo "AppleALC: 本地版本 $local_version"
fi
# 使用GitHub API检查最新版本
echo ""
echo "====== GitHub最新版本 ======"
for repo in "acidanthera/Lilu" "acidanthera/WhateverGreen" "acidanthera/AppleALC"; do
latest=$(curl -s "https://api.github.com/repos/$repo/releases/latest" | grep '"tag_name"' | sed 's/.*"tag_name": "\([^"]*\)".*/\1/')
echo "$repo: $latest"
done
5.2 自动同步EFI配置到云存储
#!/bin/bash
# sync_efi_cloud.sh
# 将EFI配置自动同步到本地Git仓库
EFI_BACKUP_REPO="$HOME/EFI-Config"
EFI_PATH="/Volumes/EFI"
# 挂载EFI
sudo diskutil mount $(diskutil list | grep EFI | head -1 | awk '{print $NF}')
# 同步文件
rsync -av --delete \
--exclude='.Trashes' \
--exclude='.fseventsd' \
"$EFI_PATH/EFI/" "$EFI_BACKUP_REPO/EFI/"
# 提交到Git
cd "$EFI_BACKUP_REPO"
git add -A
if git diff --cached --quiet; then
echo "无变更需要提交"
else
git commit -m "EFI配置更新 $(date '+%Y-%m-%d %H:%M')"
git push
echo "EFI配置已同步到远程仓库"
fi
六、安全注意事项
6.1 Shell脚本安全最佳实践
- 始终使用
set -e在错误时退出 - 使用
set -u检测未定义变量 - 使用
set -o pipefail检测管道中的错误 - 对用户输入进行验证和转义
- 避免使用
sudo除非必要,必要时提示用户输入密码 - 在删除操作前进行确认
6.2 Automator工作流安全
- 首次运行时系统会请求辅助功能权限,需要手动授权
- 包含Shell脚本的工作流无法通过代码签名,需要用户手动允许
- 分发工作流时建议附带源码说明,便于安全审计
七、总结
Automator和Shell脚本的结合为黑苹果用户提供了强大的自动化能力。从简单的文件处理到复杂的系统维护,从图形化的工作流录制到精确的命令行控制,这两种工具互为补充,覆盖了几乎所有的自动化需求。核心建议:
- 从简单开始:先创建简单的快速操作,逐步构建复杂工作流
- 善用文件夹操作:实现真正的"无感自动化"
- 脚本版本管理:将所有Shell脚本纳入Git管理
- 安全优先:所有脚本遵循安全编码规范
- 定期审查:定期检查launchd定时任务和自动化脚本的有效性
自动化是效率的倍增器。当你把重复性任务交给机器处理,就能将精力集中在真正有创造性的工作上——这才是黑苹果用户追求的终极目标。


评论(0)