1. Mac可执行脚本基础解析
在MacOS环境下,可执行脚本是提升工作效率的利器。与Windows系统不同,Mac基于Unix体系,其脚本执行机制有着独特的权限系统和解释器选择。一个典型的Mac可执行脚本通常以.sh或.command为扩展名,但文件扩展名并非必要条件——关键在于文件权限和shebang声明。
重要提示:在Mac上创建脚本时,务必注意文件换行符应为LF(Unix格式),而非CRLF(Windows格式),否则可能导致脚本无法正常执行。
1.1 脚本权限设置
MacOS继承自Unix的权限系统要求脚本文件必须具有可执行权限。通过终端执行以下命令赋予权限:
chmod +x your_script.sh这个命令实际上是在修改文件的mode位,+x表示给所有者(user)、所属组(group)和其他用户(other)都添加执行权限。更精细的权限控制可以使用数字模式,比如chmod 755表示所有者有rwx权限,而组和其他用户只有rx权限。
1.2 Shebang详解
Shebang(#!)是脚本第一行的特殊声明,指定了解释器路径。常见的有:
#!/bin/bash # 使用系统默认Bash #!/usr/bin/env python3 # 使用环境中的Python3 #!/usr/bin/perl # 使用Perl解释器env的使用特别重要,它会在用户的PATH环境变量中查找解释器,使脚本更具可移植性。当你在不同机器上运行脚本时,如果解释器安装路径不同,使用env可以避免硬编码路径带来的问题。
2. 创建Mac专用脚本的完整流程
2.1 基础脚本创建步骤
- 使用文本编辑器创建新文件,例如
hello_world.sh - 首行添加shebang:
#!/bin/bash - 编写脚本内容,例如:
echo "当前用户:$(whoami)" echo "系统版本:$(sw_vers -productVersion)" echo "CPU架构:$(uname -m)" - 保存文件后,在终端导航到脚本目录执行:
chmod +x hello_world.sh ./hello_world.sh
2.2 制作双击可执行的.command文件
Mac用户更习惯双击运行程序,可以创建.command文件实现:
- 新建文本文件,命名为
demo.command - 添加执行权限:
chmod +x demo.command - 文件内容示例:
#!/bin/bash open -a Calculator # 打开计算器 osascript -e 'display notification "任务完成" with title "提示"' - 双击运行时可能遇到安全性拦截,需在系统设置中允许:
- 前往"系统偏好设置 > 安全性与隐私 > 通用"
- 在"允许从以下位置下载的App"下选择"App Store和被认可的开发者"
- 如果仍被阻止,右键文件选择"打开"可临时绕过
2.3 脚本打包为应用程序
对于更复杂的脚本,可以打包成Mac应用:
- 使用Automator创建"应用程序"类型工作流
- 添加"运行Shell脚本"操作
- 粘贴脚本代码,保存为.app文件
- 右键.app文件选择"显示包内容"可进一步定制图标和资源
3. 高级脚本技巧与实战案例
3.1 处理带空格的路径
MacOS文件名常含空格,脚本中必须正确处理:
# 错误方式 cd /Applications/My App/ # 正确方式一:引号包裹 cd "/Applications/My App/" # 正确方式二:转义空格 cd /Applications/My\ App/3.2 获取管理员权限
需要root权限的操作可以使用sudo,但要注意安全:
#!/bin/bash # 检查是否为root if [ "$(id -u)" -ne 0 ]; then echo "正在请求管理员权限..." sudo "$0" "$@" exit $? fi # 这里是需要root权限的操作 echo "现在以root身份运行"3.3 跨版本兼容处理
针对不同MacOS版本编写兼容脚本:
#!/bin/bash os_version=$(sw_vers -productVersion) major_version=$(echo $os_version | cut -d. -f1) if [ "$major_version" -ge 12 ]; then # Monterey及以后版本的处理 defaults write com.apple.screencapture disable-shadow -bool true else # 旧版本的处理 defaults write com.apple.screencapture type jpg fi4. 实用脚本案例库
4.1 系统信息收集脚本
#!/bin/bash echo "=== 系统诊断报告 ===" > system_report.txt echo "生成时间: $(date)" >> system_report.txt echo "\n--- 硬件信息 ---" >> system_report.txt system_profiler SPHardwareDataType >> system_report.txt echo "\n--- 磁盘使用 ---" >> system_report.txt df -h >> system_report.txt echo "\n--- 内存使用 ---" >> system_report.txt top -l 1 -s 0 | grep PhysMem >> system_report.txt open system_report.txt4.2 批量图片处理脚本
#!/bin/bash # 依赖:安装ImageMagick (brew install imagemagick) input_dir="$HOME/Pictures/raw" output_dir="$HOME/Pictures/processed" mkdir -p "$output_dir" for file in "$input_dir"/*.{jpg,png}; do if [ -f "$file" ]; then filename=$(basename "$file") convert "$file" -resize 50% -quality 85% "$output_dir/${filename%.*}_optimized.${filename##*.}" fi done echo "已完成 $(ls "$output_dir" | wc -l) 张图片处理"4.3 网络状态监控
#!/bin/bash log_file="$HOME/network_monitor.log" target_host="www.apple.com" while true; do timestamp=$(date "+%Y-%m-%d %H:%M:%S") ping -c 1 "$target_host" > /dev/null 2>&1 if [ $? -eq 0 ]; then status="UP" else status="DOWN" fi echo "$timestamp - $target_host is $status" >> "$log_file" sleep 60 done5. 调试与优化技巧
5.1 脚本调试方法
语法检查模式:
bash -n script.sh # 只检查语法不执行详细执行跟踪:
bash -x script.sh # 打印每条执行的命令局部调试:
set -x # 开始调试 # 要调试的代码段 set +x # 结束调试
5.2 性能优化建议
- 减少子进程创建:
$(command)会创建子进程,在循环中应尽量避免 - 使用内置字符串处理代替awk/sed等外部命令
- 大量文件操作时使用
find -exec比循环更高效 - 考虑将部分逻辑用Python/Perl等高级语言实现
5.3 安全注意事项
永远验证用户输入:
read -p "输入目录: " dir if [ ! -d "$dir" ]; then echo "错误:目录不存在" >&2 exit 1 fi避免使用eval,除非绝对必要
设置安全的默认权限:
umask 077 # 新建文件默认权限600敏感信息不要硬编码在脚本中,考虑使用Keychain:
# 存储密码 security add-generic-password -a "$USER" -s "script_api_key" -w "secret" # 读取密码 api_key=$(security find-generic-password -a "$USER" -s "script_api_key" -w)
6. 环境配置与管理
6.1 使用Homebrew管理依赖
Homebrew是Mac上必备的包管理器,脚本中可以检查并自动安装依赖:
#!/bin/bash # 检查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 # 检查并安装ImageMagick if ! brew list imagemagick &> /dev/null; then echo "正在安装ImageMagick..." brew install imagemagick fi6.2 环境变量管理
正确管理环境变量使脚本更具可移植性:
#!/bin/bash # 设置脚本自身所在目录为工作目录 SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd) cd "$SCRIPT_DIR" # 加载自定义环境变量 if [ -f ".env" ]; then export $(grep -v '^#' .env | xargs) fi6.3 创建脚本开发环境
专业的脚本开发需要标准化环境:
#!/bin/bash # 创建项目结构 mkdir -p ~/script_project/{bin,lib,test,data/logs} touch ~/script_project/{README.md,.gitignore,.env} # 安装开发工具 brew install shellcheck shfmt bash-completion # 配置VS Code if [ -d "/Applications/Visual Studio Code.app" ]; then code --install-extension timonwong.shellcheck code --install-extension foxundermoon.shell-format fi7. 图形化界面集成
7.1 使用osascript创建对话框
#!/bin/bash # 简单通知 osascript -e 'display notification "数据处理完成" with title "脚本通知"' # 获取用户输入 response=$(osascript -e 'text returned of (display dialog "请输入文件名:" default answer "output")') # 文件选择对话框 file_path=$(osascript -e 'choose file name' 2>/dev/null)7.2 进度条显示
#!/bin/bash total=100 for ((i=0; i<=$total; i++)); do percent=$((i * 100 / total)) osascript -e "tell application \"System Events\" to display dialog \"进度: $percent%\" buttons {\"取消\"} default button 1 giving up after 1" sleep 0.1 done7.3 系统菜单栏应用
使用Platypus工具可以将脚本打包为菜单栏应用,或直接创建:
#!/bin/bash # 需要先安装SwiftDialog: brew install swiftdialog # 创建菜单栏项 echo '#!/bin/bash echo "菜单项1 | bash=/usr/bin/open param1=-a param2=Calculator terminal=false" echo "---" echo "刷新 | refresh=true"' > ~/.config/argos/myscript.1s.sh chmod +x ~/.config/argos/myscript.1s.sh