xcrun 与 Xcode 命令行工具
# xcrun 与 Xcode 命令行工具(iOS 常用实测版)
实测环境:Xcode 27.0 (Build 27A266a) / xcrun version 72 / macOS Apple Silicon 重点内容:App 安装/卸载、模拟器与真机(device)管理
# xcrun 是什么
xcrun 是 Xcode 命令行工具的统一入口:在「当前激活的开发者目录」中查找并执行开发工具,无需关心工具的实际安装路径。它解决两个问题:
- 路径无关——工具在
/Applications/Xcode.app/Contents/Developer/usr/bin/深处,xcrun simctl直接可用 - 多版本切换——
xcode-select切换 Xcode 版本后,xcrun自动跟着切换
xcrun --version # xcrun version 72.
xcrun --find simctl # 打印工具实际路径而不执行
xcrun --sdk iphoneos --find clang # 指定 SDK 下查找
xcrun clang --version # 直接透传执行任意工具
2
3
4
# 帮助与自查体系(遇到问题先查这里)
simctl / devicectl 的命令细节不用背,按需查三个入口:
xcrun simctl help # 顶部 = <device> 参数规则,往下 = 全部子命令列表
xcrun simctl help install # 任意子命令的用法(help <subcommand>)
man simctl # 完整手册(simctl 有独立 man page)
xcrun devicectl --help # devicectl 总帮助
xcrun devicectl device install app --help # devicectl 任意子命令的 --help
2
3
4
5
6
<device> 参数的三种写法(simctl help 原文:a device UDID or the special "booted" string):
| 写法 | 说明 |
|---|---|
| UDID | simctl list 里的 UUID,最精确;多开模拟器时必用 |
| 设备名称 | 如 "iPhone 15 Pro"(含空格要引号),实测可用 |
booted | 当前已启动的设备;多台 booted 时随机挑一台,不保证哪台 |
部分命令额外支持
all(如shutdown all、erase all、delete unavailable),但install不支持all。
# xcode-select — 工具来源与安装/卸载
xcrun 执行哪个 Xcode 的工具,由 xcode-select 决定。
# 安装(Command Line Tools)
# 场景1:完整 Xcode 已装——无需单独装 CLT,切换开发者目录即可
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# 场景2:不装 Xcode 只要命令行工具(服务器/CI/git 编译需要)
xcode-select --install # 弹窗安装 /Library/Developer/CommandLineTools
# 验证
xcode-select -p
# /Applications/Xcode.app/Contents/Developer ← 当前用完整 Xcode
# /Library/Developer/CommandLineTools ← 当前用独立 CLT
2
3
4
5
6
7
8
9
10
# 卸载(Command Line Tools)
# 独立 CLT 的卸载方式(实测路径)
sudo rm -rf /Library/Developer/CommandLineTools
2
完整 Xcode 的卸载就是删 /Applications/Xcode.app + 清理残留:
sudo rm -rf ~/Library/Developer/Xcode/DerivedData # 构建缓存(可单独清理,释放空间)
sudo rm -rf ~/Library/Developer/CoreSimulator # 模拟器数据(慎删,会丢所有模拟器)
2
# 重点一:模拟器管理(simctl)
# 设备列表与查找
xcrun simctl list devices available # 可用设备(按运行时分组)
xcrun simctl list devices # 全部设备(含已创建/不可用)
xcrun simctl list runtimes # 已装运行时(iOS 17.0 等)
xcrun simctl list devicetypes # 支持的设备型号
2
3
4
实测输出示例:
== Devices ==
-- iOS 17.0 --
iPhone 15 Pro (80CCEF25-6BD0-4C3A-9A4E-896064E088F7) (Shutdown)
2
3
括号里的 UUID 是设备唯一标识,后续命令用 UUID 或名称均可。
# 创建 / 删除设备
xcrun simctl create "iPhone 15 Test" com.apple.CoreSimulator.SimDeviceType.iPhone-15-Pro com.apple.CoreSimulator.SimRuntime.iOS-17-0
xcrun simctl delete "iPhone 15 Test" # 删除指定设备
xcrun simctl delete unavailable # 清理所有不可用设备(升级 Xcode 后常做)
2
3
# 启动 / 关闭 / 重置
xcrun simctl boot "iPhone 15 Pro" # 启动
xcrun simctl bootstatus "iPhone 15 Pro" -b # 等待启动完成
open -a Simulator # 打开 Simulator.app 看画面
xcrun simctl shutdown "iPhone 15 Pro" # 关闭
xcrun simctl shutdown all # 关闭全部
xcrun simctl erase "iPhone 15 Pro" # 重置(清空数据恢复出厂,排查脏数据问题神器)
2
3
4
5
6
# ⭐ 安装 App(重点)
xcrun simctl install <device> <path/to/App.app>
# 例:安装构建产物
xcrun simctl install "iPhone 15 Pro" build/Debug-iphonesimulator/MyApp.app
2
3
注意:模拟器装的是 .app bundle(非 ipa),且必须是模拟器架构(iphonesimulator 构建)产物。
# ⭐ 卸载 App(重点)
xcrun simctl uninstall <device> <bundle-id>
# 例:
xcrun simctl uninstall "iPhone 15 Pro" com.example.MyApp
2
3
安装用路径,卸载用 bundle id——不对称,高频踩坑点。
# 启动 / 终止 App
xcrun simctl launch <device> <bundle-id> # 启动
xcrun simctl launch <device> <bundle-id> -- -arg1 value # 传启动参数(-- 后)
xcrun simctl terminate <device> <bundle-id> # 终止
2
3
# 截图 / 录屏
xcrun simctl io "iPhone 15 Pro" screenshot ~/Desktop/shot.png
xcrun simctl io "iPhone 15 Pro" recordVideo ~/Desktop/demo.mp4 # Ctrl+C 结束
2
# 隐私授权(免弹窗调试)
# 一次性授予全部权限(相机/定位/通讯录…),跳过系统弹窗
xcrun simctl privacy "iPhone 15 Pro" grant all com.example.MyApp
# 单独授予定位(精确)
xcrun simctl privacy "iPhone 15 Pro" grant location com.example.MyApp
# 撤销
xcrun simctl privacy "iPhone 15 Pro" revoke all com.example.MyApp
# 重置
xcrun simctl privacy "iPhone 15 Pro" reset all com.example.MyApp
2
3
4
5
6
7
8
# 其他常用
xcrun simctl openurl "iPhone 15 Pro" "myapp://page/detail" # 打开 URL/DeepLink
xcrun simctl get_app_container "iPhone 15 Pro" com.example.MyApp data # 查看沙盒路径
xcrun simctl keychain "iPhone 15 Pro" reset # 重置钥匙串(调试登录态)
2
3
# 重点二:真机管理(devicectl,Xcode 15+)
devicectl 是 Apple 官方的真机命令行工具,替代已废弃的 ios-deploy / ideviceinstaller。通过 USB 或 Wi-Fi 连接的物理设备均可管理。
# 设备列表
xcrun devicectl list devices
实测输出(--device 支持名称/UDID/序列号多种定位方式):
Name Identifier State Model Reality
YC-PHONE 00008130-00162C3C2891401C connected iPhone 15 Pro (iPhone16,1) physical
2
# ⭐ 安装 App(重点)
xcrun devicectl device install app --device <标识> <path/to/App.app>
# 标识可以是 UDID / 序列号 / 设备名称
# 例:用设备名安装
xcrun devicectl device install app --device YC-PHONE build/Debug-iphoneos/MyApp.app
2
3
4
真机装的是 iphoneos 架构的 .app(Debug-iphoneos 目录),且签名/描述文件需匹配该设备。
# ⭐ 卸载 App(重点)
xcrun devicectl device uninstall app --device <标识> <bundle-id>
# 例:
xcrun devicectl device uninstall app --device YC-PHONE com.example.MyApp
2
3
与 simctl 相同的规律:装用路径,卸用 bundle id。
# 启动 / 终止 App
xcrun devicectl device process launch --device YC-PHONE com.example.MyApp
xcrun devicectl device process launch --device YC-PHONE com.example.MyApp --console # 附带控制台输出
xcrun devicectl device process terminate --device YC-PHONE com.example.MyApp
2
3
# simctl vs devicectl 对照
| 操作 | 模拟器 simctl | 真机 devicectl |
|---|---|---|
| 设备列表 | simctl list devices | devicectl list devices |
| 安装 | simctl install <dev> <path> | device install app --device <id> <path> |
| 卸载 | simctl uninstall <dev> <bundle-id> | device uninstall app --device <id> <bundle-id> |
| 启动 | simctl launch <dev> <bundle-id> | device process launch --device <id> <bundle-id> |
| 产物架构 | iphonesimulator (.app) | iphoneos (.app,需有效签名) |
| 截图 | simctl io <dev> screenshot | Xcode GUI / xcrun devicectl device ... copy |
# 其他常用子工具
xcrun xcodebuild -version # 构建(xcodebuild 本身也经 xcrun)
xcrun instruments -h # 性能分析
xcrun notarytool submit xxx.ipa ... # 公证上传(App Store 外分发)
xcrun simctl # 见上文
xcrun altool # 旧上传工具(已由 notarytool 取代)
2
3
4
5
# 常见问题排查
# xcode-select: unable to get active developer directory
CLT 未安装或 Xcode 被移动/删除后路径失效:
xcode-select --install # 装 CLT
# 或
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
2
3
# 切换 Xcode 后工具版本不对
未设置 DEVELOPER_DIR 时,xcrun/系统 xcodebuild 使用 xcode-select 选定的开发者目录;DEVELOPER_DIR 可以覆盖当前命令及其子进程使用的目录。xcode-select -p 本身不能证明某个命令没有被环境变量覆盖。
# 查看系统选择、当前环境及实际工具版本
xcode-select -p
printenv DEVELOPER_DIR
xcrun --find xcodebuild
xcodebuild -version
# 为单次调用选择另一版本,不修改系统默认目录
DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer xcrun xcodebuild -version
2
3
4
5
6
7
8
printenv 在变量未设置时返回非零;在启用 set -e 的脚本中,可用 printenv DEVELOPER_DIR || true 做诊断。示例中的 Xcode 路径必须对应本机实际安装位置。参考:Apple 命令行工具选择 (opens new window)。
# simctl 找不到某设备
- 设备名与 UDID 用
xcrun simctl list devices核对(名称含特殊字符时优先用 UDID) - 升级 Xcode 后旧运行时失效:
xcrun simctl delete unavailable清理 - 模拟器卡死:
xcrun simctl shutdown all后重启
# devicectl 显示不出真机
- 设备需在「设置 → 隐私与安全性 → 开发者模式」中开启开发者模式(iOS 16+)
- USB 连接首次需在设备上点「信任」
- Xcode 15 以下没有 devicectl(旧版用 ios-deploy)