Table of Contents
- Overview
- Execution Methods
- AppleScript Core Syntax
- JXA Core Syntax
- Common Scenarios Quick Reference
- 5.1 Dialogs and Notifications
- 5.2 Clipboard Operations
- 5.3 Finder File Operations
- 5.4 Safari / Browser Control
- 5.5 Mail Email Operations
- 5.6 System UI Automation
- 5.7 Calendar
- 5.8 Numbers / Data Processing
- 5.9 Terminal/Shell Commands
- Advanced Scenarios
- 6.1 Window Management
- 6.2 Audio Device Control
- 6.3 Bluetooth and Network
- 6.4 Screen and Screenshots
- 6.5 System Monitoring
- 6.6 File System Monitoring
- 6.7 Compression and Disk Images
- 6.8 Time Machine
- 6.9 Security and Signing
- 6.10 Speech Synthesis
- Error Handling
- Return Value Handling
- Permissions and Security
- Debugging Tips
- Workflow Recommendations
- Application API Dictionary
Overview
osascript is a built-in script runner in macOS that supports two languages:
- AppleScript: A traditional scripting language with syntax close to English and the best compatibility
- JXA(JavaScript for Automation): Modern JS syntax, more flexible, suitable for complex logic
Execution Methods
Basic Invocation
# AppleScript(默认)
osascript -e 'tell application "Finder" to activate'
# JXA
osascript -l JavaScript -e 'Application("Finder").activate()'
# 执行脚本文件
osascript /path/to/script.applescript
osascript -l JavaScript /path/to/script.js
Execute via bash_tool
# 推荐:heredoc 方式,适合多行脚本
bash_tool("""osascript << 'EOF'
tell application "Safari"
activate
open location "https://example.com"
end tell
EOF""")
AppleScript Core Syntax
Basic Structure
-- 单行注释
(*
多行注释
*)
-- 变量
set myVar to "Hello"
set myNum to 42
set myList to {1, 2, 3}
-- 条件
if myNum > 10 then
display dialog "大于10"
else
display dialog "不大于10"
end if
-- 循环
repeat with i from 1 to 5
log i
end repeat
repeat with item in myList
log item
end repeat
-- 函数
on greet(name)
return "Hello, " & name
end greet
Tell Block (Controlling Applications)
tell application "应用名"
-- 在此块内的命令发送给该应用
activate -- 激活/置前
quit -- 退出
end tell
-- 嵌套 tell(操作应用内的元素)
tell application "Finder"
tell front window
set current view to list view
end tell
end tell
JXA Core Syntax
Basic Structure
// 获取应用引用
const app = Application("Finder")
const safari = Application("Safari")
// 当前应用(脚本编辑器/osascript 自身)
const app = Application.currentApplication()
app.includeStandardAdditions = true // 启用标准附加功能(对话框、通知等)
// 激活应用
safari.activate()
// 系统事件(UI 自动化)
const se = Application("System Events")
Common Scenarios Quick Reference
1. Dialogs and Notifications
AppleScript:
-- 显示对话框
display dialog "请输入名字:" default answer "张三" with title "输入"
set userName to text returned of result
-- 确认对话框
set choice to button returned of (display dialog "确定继续?" buttons {"取消", "确定"} default button "确定")
-- 通知
display notification "任务完成!" with title "提醒" subtitle "成功"
-- 选择文件
set theFile to choose file with prompt "请选择文件:"
set filePath to POSIX path of theFile
-- 选择文件夹
set theFolder to choose folder with prompt "请选择文件夹:"
JXA:
const app = Application.currentApplication()
app.includeStandardAdditions = true
// 对话框
const result = app.displayDialog("请输入名字:", {
defaultAnswer: "张三",
withTitle: "输入",
buttons: ["取消", "确定"],
defaultButton: "确定"
})
const userName = result.textReturned
// 通知
app.displayNotification("任务完成!", {
withTitle: "提醒",
subtitle: "成功"
})
2. Clipboard Operations
-- 读取剪贴板
set clipContent to the clipboard
-- 写入剪贴板
set the clipboard to "新内容"
-- 读取特定类型
set clipText to the clipboard as text
// JXA
const app = Application.currentApplication()
app.includeStandardAdditions = true
const clip = app.theClipboard()
app.setTheClipboardTo("新内容")
3. Finder File Operations
tell application "Finder"
-- 获取桌面路径
set desktopPath to POSIX path of (path to desktop)
-- 创建文件夹
make new folder at desktop with properties {name:"新文件夹"}
-- 移动文件
move file "Macintosh HD:Users:user:file.txt" to trash
-- 获取选中文件
set selectedItems to selection
repeat with f in selectedItems
log POSIX path of (f as alias)
end repeat
-- 打开文件
open POSIX file "/Users/user/document.pdf"
end tell
4. Safari / Browser Control
tell application "Safari"
activate
-- 打开 URL
open location "https://www.example.com"
-- 获取当前页面 URL 和标题
set currentURL to URL of current tab of front window
set pageTitle to name of current tab of front window
-- 执行 JavaScript
do JavaScript "document.title" in current tab of front window
-- 新建标签页
tell front window
set newTab to make new tab
set URL of newTab to "https://www.google.com"
end tell
end tell
5. Mail Email Operations
tell application "Mail"
-- 创建新邮件
set newMsg to make new outgoing message with properties {
subject: "测试邮件",
content: "这是邮件正文",
visible: true
}
tell newMsg
make new to recipient with properties {
name: "收件人",
address: "recipient@example.com"
}
end tell
-- 发送
send newMsg
end tell
6. System UI Automation (System Events)
tell application "System Events"
-- 按键
keystroke "c" using {command down} -- Cmd+C
key code 36 -- 回车键
-- 点击菜单栏
tell process "Finder"
click menu item "新建文件夹" of menu "文件" of menu bar 1
end tell
-- 获取所有运行中的应用
set runningApps to name of every process whose background only is false
end tell
-- 模拟点击 UI 元素
tell application "System Events"
tell process "Calculator"
click button "1"
click button "+"
click button "2"
click button "="
end tell
end tell
7. Calendar
tell application "Calendar"
-- 创建事件
tell calendar "工作"
make new event with properties {
summary: "团队会议",
start date: date "2024-01-15 14:00",
end date: date "2024-01-15 15:00",
description: "季度复盘"
}
end tell
end tell
8. Terminal/Shell Commands
-- 在 AppleScript 中执行 shell 命令
set result to do shell script "ls -la ~/Desktop"
set result to do shell script "python3 /path/to/script.py"
-- 需要管理员权限
do shell script "sudo command" with administrator privileges
9. Numbers / Data Processing
tell application "Numbers"
tell front document
tell active sheet
tell table 1
-- 读取单元格
set cellVal to value of cell "A1"
-- 写入单元格
set value of cell "B1" to 42
-- 获取行数
set rowCount to row count
end tell
end tell
end tell
end tell
Advanced Scenarios
6.1 Window Management
-- 调整窗口大小/位置
tell application "System Events"
tell process "Code"
set position of front window to {100, 100}
set size of front window to {800, 600}
end tell
end tell
-- 最小化所有窗口
tell application "System Events"
keystroke "m" using command down
end tell
-- 获取屏幕分辨率
tell application "Finder"
get bounds of window of desktop
end tell
6.2 Audio Device Control
# 需要: brew install switchaudio-osx
-- 获取当前输出设备
set currentDevice to do shell script "SwitchAudioSource -c"
-- 切换音频输出
do shell script "SwitchAudioSource -s \"MacBook Pro Speakers\""
-- 设置音量
set volume output volume 50
set volume input volume 30
6.3 Bluetooth and Network
# 需要: brew install blueutil
-- 蓝牙开关
do shell script "blueutil --power 1" -- 开启
do shell script "blueutil --power 0" -- 关闭
-- 列出配对设备
set pairedDevices to do shell script "blueutil --paired"
-- 获取 WiFi 状态
set wifiStatus to do shell script "airport -I | grep state | awk '{print $2}'"
-- 切换 WiFi
do shell script "networksetup -setairportpower en0 on"
-- 获取 IP
set myIP to do shell script "ifconfig | grep inet | grep -v inet6 | awk '{print $2}' | head -1"
6.4 Screen and Screenshots
-- 截屏到剪贴板
do shell script "screencapture -c"
-- 选择区域截屏
do shell script "screencapture -i ~/Desktop/cap.png"
-- 全屏截屏带阴影
do shell script "screencapture -x ~/Desktop/fullscreen.png"
-- 定时截屏
do shell script "screencapture -T 5 ~/Desktop/delay.png"
6.5 System Monitoring
-- CPU 负载
set cpuLoad to do shell script "uptime | awk -F'load averages: ' '{print $2}'"
-- 内存压力
set memoryFree to do shell script "memory_pressure | grep 'System-wide memory free percentage' | awk '{print $5}'"
-- 电池状态
set batteryPercent to do shell script "pmset -g batt | grep -Eo '[0-9]+%' | head -1"
-- 磁盘空间
set freeSpace to do shell script "df -h / | tail -1 | awk '{print $4}'"
-- 获取硬件信息
set serialNumber to do shell script "system_profiler SPHardwareDataType | grep 'Serial Number' | awk '{print $4}'"
set cpuInfo to do shell script "sysctl -n machdep.cpu.brand_string"
6.6 File System Monitoring
-- 使用 fswatch 监控目录变化 (需要: brew install fswatch)
do shell script "fswatch -1 /path/to/watch && echo 'Changed'"
-- 获取文件扩展属性
set xattr to do shell script "xattr -l /path/to/file"
-- Spotlight 搜索
set searchResults to do shell script "mdfind 'kind:image && kMDItemPixelHeight > 2000'"
-- 获取文件元数据
set createDate to do shell script "mdls -n kMDItemContentCreationDate /path/to/file"
6.7 Compression and Disk Images
-- 创建加密压缩包
do shell script "zip -e -r secure.zip folder/"
-- 解压特定文件
do shell script "unzip -j archive.zip 'specific/file.txt' -d /tmp/"
-- 创建 DMG 镜像
do shell script "hdiutil create -srcfolder /path/to/folder -volname Name output.dmg"
-- 挂载 DMG
do shell script "hdiutil attach output.dmg"
-- 卸载 DMG
do shell script "hdiutil detach /Volumes/Name"
-- 转换 DMG 格式
do shell script "hdiutil convert input.dmg -format UDZO -o compressed.dmg"
6.8 Time Machine
-- 开始备份
do shell script "tmutil startbackup"
-- 排除文件
do shell script "tmutil addexclusion /path/to/folder"
-- 查看备份状态
set backupStatus to do shell script "tmutil status"
-- 列出备份历史
set backupList to do shell script "tmutil listbackups"
-- 恢复快照
do shell script "tmutil restore /path/to/backup/file /destination/"
6.9 Security and Signing
-- 代码签名检查
set codesignInfo to do shell script "codesign -dv /Applications/App.app 2>&1 | head -10"
-- 检查 SIP 状态
set sipStatus to do shell script "csrutil status"
-- 检查 Gatekeeper
set gatekeeper to do shell script "spctl --status"
-- 公证状态查询 (需要配置 keychain profile)
set notarization to do shell script "xcrun notarytool history --keychain-profile AC_PROFILE 2>&1 | head -5"
6.10 Speech Synthesis
-- 朗读文本
say "Hello World"
-- 指定语音/速度
say "Hello" using "Samantha" speaking rate 150
-- 保存为音频文件
say "Hello World" saving to alias "Macintosh HD:Users:name:Desktop:out.aiff"
-- 列出可用语音
set voices to do shell script "say -v '?' | cut -d ' ' -f 1-2"
-- 中文语音
say "你好世界" using "Ting-Ting"
Error Handling
AppleScript
try
-- 可能出错的代码
tell application "Safari"
set x to URL of current tab of front window
end tell
on error errMsg number errNum
display dialog "错误 " & errNum & ": " & errMsg
end try
JXA
try {
const safari = Application("Safari")
const url = safari.windows[0].currentTab.url()
} catch(e) {
console.log("错误: " + e.message)
}
Return Value Handling
The output of osascript is printed to stdout, and bash_tool can capture it:
# 返回值自动输出到 stdout
result=$(osascript -e 'return "Hello World"')
echo $result # Hello World
# 多行返回(列表用逗号分隔)
osascript -e 'return {"apple", "banana", "cherry"}'
# 输出: apple, banana, cherry
Permissions and Security Considerations
- First Run Requires Authorization: System Events, accessibility control, etc. require authorizing Terminal/apps in "System Settings → Privacy & Security → Accessibility"
- Sandbox Restrictions: Mac App Store apps may restrict AppleScript access
- Permission check:
tell application "System Events"
if UI elements enabled then
-- 有辅助功能权限
else
display dialog "请在系统设置中开启辅助功能权限"
end if
end tell
Debugging tips
# 详细错误输出
osascript -e 'tell application "Finder" to ...' 2>&1
# 脚本编辑器日志(AppleScript)
log "调试信息: " & myVar
# JXA 控制台输出
console.log("调试:", someValue)
# 测试脚本是否有语法错误(不执行)
osacompile -o /dev/null script.applescript
Workflow recommendations
- Simple one-line operation → use the
-eparameter to execute directly - Multi-step automation → write it as a script file and use
osascriptto execute - Requires user interaction → use
display dialogto collect input - App UI has no AppleScript support → switch to
System Eventsto simulate mouse and keyboard - Complex data processing → use JXA (JS syntax is more flexible) together with
do shell scriptto call Python/Ruby
For detailed app-specific APIs, refer to:references/app-dictionaries.md