深入解析与实战:全面修复 Xcode phasescriptexecution failed: nonzero exit code
错误
在使用 Xcode 进行 iOS 或 macOS 开发时,phasescriptexecution failed: nonzero exit code
这个错误信息无疑是开发者最头疼的错误之一。它不像语法错误那样直接指向代码问题,也不像链接错误那样指向库或依赖问题,它是一个非常通用的错误提示,意味着在 Xcode 的某个“构建阶段”(Build Phase)中的一个“运行脚本阶段”(Run Script Phase)执行失败了,并且该脚本的退出代码(Exit Code)不是表示成功的零(0),而是非零的数值。
这个错误之所以令人头疼,是因为它并没有直接告诉你失败的 原因,只告诉你 结果。脚本执行失败的原因可能是千差万化、五花八门的,从简单的语法错误、文件缺失、权限问题,到复杂的环境变量配置、第三方工具链故障、依赖管理问题,甚至临时的 Xcode 缓存或环境异常,都可能导致这个错误。
本文将带领你深入理解这个错误,并提供一套系统化、详细的排查和修复方案,帮助你从容应对这一挑战。
一、理解错误的核心:构建阶段与运行脚本
在 Xcode 中,一个 App 或 Framework 的构建过程被分解为一系列“构建阶段”(Build Phases)。这些阶段按照特定的顺序执行,共同完成从源代码到最终可执行文件的转换。常见的构建阶段包括:
- Compile Sources: 编译源代码文件(如
.m
,.swift
)。 - Process Resources: 处理资源文件(如图片、音频、
.plist
)。 - Compile Assets: 编译 Asset Catalogs (
.xcassets
)。 - Link Binary With Libraries: 将编译好的代码与所需的库(Libraries)和框架(Frameworks)链接起来。
- Copy Files: 复制文件到产品包中。
- Run Script: 执行自定义脚本。
phasescriptexecution failed: nonzero exit code
正是发生在 Run Script
阶段。开发者或项目模板可能会在构建过程中添加自定义的脚本,用于执行各种自动化任务,例如:
- 依赖管理: CocoaPods 的
Check Pods Manifest.lock
、Embed Pods Frameworks
、Copy Pods Resources
等阶段本质上就是运行脚本。 - 代码检查与格式化: 运行 SwiftLint, Danger, SwiftFormat 等工具。
- 版本控制/信息注入: 将 Git Commit Hash 或版本号写入 Info.plist 或代码中。
- 文件生成: 生成本地化文件、模型代码、或处理特定资源。
- 上传符号表: 如 Crashlytics/Firebase 的上传脚本。
- 自定义构建逻辑: 任何需要命令行工具或脚本完成的任务。
当这些脚本中的任何一个在执行过程中遇到问题,并以非零的退出代码结束时,Xcode 就会报出 phasescriptexecution failed: nonzero exit code
错误,并停止构建过程。
二、系统化排查与修复步骤
面对这个通用错误,最忌讳的是盲目尝试。一套系统化的排查流程能帮助我们快速定位问题所在。
步骤 1:初步尝试与清理(解决临时性问题)
很多时候,这个错误可能是由 Xcode 的临时缓存、索引问题或构建环境混乱引起的。先尝试一些简单的清理步骤:
- 执行 Product -> Clean Build Folder (Shift + Cmd + K): 清理当前的构建产物。这是最基本的清理。
- 删除 DerivedData 文件夹: Xcode 将中间构建文件、索引等存储在 DerivedData 文件夹中。删除它可以解决很多奇怪的问题。
- 关闭 Xcode。
- 打开终端,执行
rm -rf ~/Library/Developer/Xcode/DerivedData
。 - 或者在 Xcode 的 Preference -> Locations -> Derived Data 中点击箭头,然后删除该文件夹。
- 重新打开项目并尝试构建。
- 重启 Xcode: 有时候 Xcode 本身可能处于不稳定状态。
- 重启 Mac: 这是最后的手段,可以清理操作系统层面的临时问题。
- 检查磁盘空间: 确保你的 Mac 还有足够的磁盘空间供 Xcode 进行构建。
如果经过这些初步清理后问题依然存在,说明这不是简单的临时问题,我们需要深入挖掘。
步骤 2:定位失败的脚本(找到错误的源头)
由于 Run Script
阶段可能有很多个,我们需要确定是 哪一个 脚本失败了。这是解决问题的关键一步。
- 打开 Report Navigator (报告导航器): 在 Xcode 左侧面板中选择最右边的图标(通常是气泡形状的)。
- 选择最近一次失败的构建: 在 Report Navigator 中找到你刚刚尝试构建并失败的那一次记录(通常是红色的)。
- 展开构建过程: 点击该构建记录,展开详细的构建步骤列表。
- 查找失败的 Run Script Phase: 向下滚动,你会看到各个构建阶段。找到标有红色错误图标的
Run Script
阶段。 - 查看详细输出: 展开这个失败的
Run Script
阶段,查看其详细的构建日志(Transcript)。这是包含错误信息的“宝藏”。
仔细阅读这个日志!它会包含脚本执行过程中打印到标准输出 (stdout) 和标准错误 (stderr) 的信息。通常,真正的错误原因和更具体的错误信息(如 command not found
, Permission denied
, 脚本的语法错误提示,或者第三方工具的错误输出)都会在这里显示。
将日志中的关键错误信息复制出来,这是你进一步排查的依据。
步骤 3:分析日志中的具体错误信息
根据你在步骤 2 中找到的详细日志,分析具体的错误提示。以下是一些常见的错误信息及其对应的排查方向:
command not found: [some_command]
:- 原因: 脚本尝试执行一个命令,但该命令在脚本执行时的
$PATH
环境变量中找不到。这通常是因为 Xcode 构建环境的$PATH
与你在终端中使用的$PATH
不同。 - 排查:
- 确定脚本尝试执行的是哪个命令 (
[some_command]
)。 - 在你的终端中执行
which [some_command]
,看看命令的完整路径是什么(例如/usr/local/bin/swiftlint
)。 - 修改脚本,使用命令的完整路径执行它,而不是只使用命令名。
- 或者,尝试在脚本开头加上
#!/bin/bash -l
或#!/bin/zsh -l
(取决于你的终端使用的 shell),这会尝试加载你的 shell 配置文件(如.bash_profile
,.zshrc
),从而设置正确的$PATH
。 - 如果命令是通过
brew
,nvm
,rbenv
,asdf
,volta
等工具安装的,这些工具可能需要特殊的初始化才能在脚本环境中生效。尝试在脚本中显式地 source 这些工具的初始化脚本,例如source ~/.nvm/nvm.sh
。
- 确定脚本尝试执行的是哪个命令 (
- 原因: 脚本尝试执行一个命令,但该命令在脚本执行时的
Permission denied
:- 原因: 脚本文件本身没有执行权限,或者脚本尝试访问或写入一个没有权限的文件/目录。
- 排查:
- 确定是哪个文件或目录引发了权限问题。日志通常会指明。
- 如果是脚本文件本身,在终端中进入项目目录,找到该脚本文件,执行
chmod +x [script_file_path]
赋予执行权限。 - 如果是脚本访问的文件/目录,检查该路径的权限。确保 Xcode 或运行构建的用户有读/写权限。
- 注意,如果项目文件位于外部硬盘或网络共享上,权限问题可能更复杂。
- Syntax Error in Script:
- 原因: 脚本语言(如 Bash, Shell)本身的语法错误。
- 排查:
- 日志通常会指出是脚本文件的哪一行出现了语法错误。
- 仔细检查该行及其附近的代码,查找拼写错误、括号不匹配、缺少引号、不正确的变量使用等。
- 可以在终端中单独执行该脚本,或者将脚本内容粘贴到终端中逐行执行,以更容易发现语法问题。使用
set -e
在脚本中可以使得脚本在遇到错误时立即退出,有助于定位问题。
- Error messages related to a specific tool (CocoaPods, SwiftLint, Fastlane, etc.):
- 原因: 脚本本身可能只是调用了一个外部工具,实际的错误是那个工具产生的。
- 排查:
- 日志会包含该工具的错误输出。仔细阅读这些输出,它们往往比
nonzero exit code
更具体。 - 在终端中模拟执行脚本调用的命令: 进入你的项目根目录(或脚本实际执行的目录),复制脚本中调用外部工具的那一行命令(或者整个脚本),在终端中直接执行。这样你可以看到工具完整的、未经过滤的输出,更容易诊断问题。例如,如果日志显示 SwiftLint 失败,找到脚本中调用
swiftlint
的那一行,然后在终端里执行它。 - 检查工具的安装和版本: 确保该工具已正确安装,并且项目依赖的工具版本与你安装的版本兼容。可能需要更新或重新安装该工具 (
brew upgrade swiftlint
,gem update fastlane
,pod repo update
等)。 - 检查工具的配置文件: 许多工具依赖项目根目录下的配置文件(如
.swiftlint.yml
,Fastfile
,Podfile
)。确保这些文件存在且内容正确。
- 日志会包含该工具的错误输出。仔细阅读这些输出,它们往往比
diff: [file].lock: No such file or directory
(CocoaPods):- 原因: CocoaPods 的
Check Pods Manifest.lock
脚本在验证Podfile.lock
和Manifest.lock
文件时,找不到其中一个或两个文件。这通常发生在.gitigore
文件忽略了Pods/
目录,而你又没有先运行pod install
的情况下。 - 排查:
- 在项目根目录执行
pod install
。确保成功安装了 Pods 并且生成了Pods/
目录和Podfile.lock
/Manifest.lock
文件。 - 确保这些文件没有被
.gitignore
忽略,或者如果忽略了,在拉取代码后记得先执行pod install
。 - 如果
pod install
本身失败,需要先解决pod install
的问题。
- 在项目根目录执行
- 原因: CocoaPods 的
- Exit code is very large (e.g., 255): 有时候大的退出码可能是因为脚本被操作系统信号中断,而不是脚本内部的
exit
命令。但这比较少见,通常还是脚本内部错误。
步骤 4:针对常见问题进行修复
根据步骤 3 的分析,针对性地进行修复。以下是一些常见问题及其修复方案的详细说明:
4.1. CocoaPods 相关问题
CocoaPods 是 Run Script 错误的最常见来源之一,因为它在构建过程中添加了多个脚本阶段。
Check Pods Manifest.lock
失败:- 问题: 这个脚本比较
Podfile.lock
和Pods/Manifest.lock
两个文件的哈希值,确保它们一致。如果它们不一致(例如,你更新了 Podfile 但没运行pod install
,或者直接修改了 Podfile.lock),或者文件不存在,就会失败。 - 修复:
- 确保你已经在项目根目录执行了
pod install
,并且成功完成。 - 检查
.gitignore
文件,确保Podfile.lock
和Pods/Manifest.lock
没有被误删或忽略。Pods/
目录本身通常是被忽略的,但Podfile.lock
应该被版本控制。 - 如果问题持续,尝试:
pod deintegrate
pod clean
pod install
- 重新打开
.xcworkspace
文件(而不是.xcodeproj
)。
- 确保你已经在项目根目录执行了
- 问题: 这个脚本比较
Embed Pods Frameworks
或Copy Pods Resources
失败:- 问题: 这些脚本负责将 Pods 中的 Frameworks 和资源文件复制到你的 App Bundle 中。失败可能的原因包括:文件找不到、路径错误、权限问题、或者 Pods 安装本身有问题。
- 修复:
- 首先,确保
pod install
成功。 - 检查构建设置 (Build Settings):
FRAMEWORK_SEARCH_PATHS
是否包含了正确指向 Pods Frameworks 的路径 ($(PROJECT_DIR)/Pods
)。LIBRARY_SEARCH_PATHS
是否包含了正确指向 Pods Libraries 的路径。OTHER_LDFLAGS
是否包含了-lc++
,-ObjC
,$(OTHER_LDFLAGS)
以及特定 Pods 需要的链接器标志。
- 检查 Run Script 阶段的配置: 确保脚本路径正确,输入/输出文件列表配置正确(如果脚本依赖这些配置)。对于 CocoaPods 生成的脚本,通常不需要手动修改,但需要确保 Pods 的安装过程是正确的。
-
M1/M2 Mac 兼容性问题: 如果你在 Apple Silicon (M1/M2/M3) Mac 上开发,并且使用了包含 Intel (x86_64) 二进制文件的 Pods,可能会遇到兼容性问题。
- 尝试在终端中运行
pod install
时加上架构前缀:arch -x86_64 pod install
. - 在 Build Settings 中检查
Excluded Architectures
(EXCLUDED_ARCHS
),对于 Debug 或 Release 配置,确保没有错误地排除了arm64
或包含了i386 x86_64
(除非你确实需要模拟器兼容性)。对于 Apple Silicon Mac,通常需要排除arm64
模拟器 架构(arm64-simulator
)当你依赖的库还没有提供 arm64 切片时,或者在特定情况下需要包含arm64
架构 (arm64
)。这部分比较复杂,通常 CocoaPods 官方文档有更详细的说明。最常见的修复是在你的 Podfile 中加入:
“`ruby
# 在 target ‘YourTarget’ do … end 块外部
plugin ‘cocoapods-user-defined-build-types’ # 如果你使用了特定构建类型
# 在 target ‘YourTarget’ do … end 块内部
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings[‘ARCHS’] = ‘arm64 x86_64’ # 或者其他需要的架构组合
# 对于模拟器兼容性问题,可能需要排除arm64模拟器架构
# config.build_settings[‘EXCLUDED_ARCHS[sdk=iphonesimulator*]’] = ‘arm64’
end
end
end
``
arm64
(注意:排除模拟器架构是针对旧的、不兼容 M1 模拟器的 Pods。现在大多数流行库应该都已更新。)
~/Library/Caches/CocoaPods
* **清理 Pods 缓存:** 有时 Pods 的本地缓存损坏也会导致问题。尝试删除和
~/.cocoapods目录(谨慎操作),然后重新运行
pod install`。 - 尝试在终端中运行
- 首先,确保
4.2. 环境变量与 PATH 问题
如前所述,脚本执行时的环境可能与你的终端环境不同。
- 问题: 脚本调用的命令找不到(
command not found
)或者使用了错误版本的工具。 - 修复:
- 使用绝对路径: 找到命令的完整路径(使用
which command_name
),然后在脚本中直接使用完整路径。例如,将swiftlint
改为/usr/local/bin/swiftlint
。 - 加载 Shell 配置文件: 在脚本开头添加
#!/bin/bash -l
或#!/bin/zsh -l
。-l
参数会让 shell 作为登录 shell 启动,从而加载用户的配置文件(如.bash_profile
,.zshrc
),这些文件通常设置了$PATH
和其他环境变量。 -
显式 sourcing 工具环境: 如果你使用
nvm
,rbenv
,asdf
等工具管理 Node, Ruby, 或其他语言版本,这些工具通常需要在 shell 启动时 sourcing 一个脚本来设置当前环境。你可以在 Xcode 脚本的开头显式地 sourcing 这些脚本:
“`bash
# 对于 nvm
export NVM_DIR=”$HOME/.nvm”
[ -s “$NVM_DIR/nvm.sh” ] && . “$NVM_DIR/nvm.sh” # This loads nvm
[ -s “$NVM_DIR/bash_completion” ] && . “$NVM_DIR/bash_completion” # This loads nvm bash_completion
# 或者根据你的安装方式调整路径对于 rbenv
eval “$(rbenv init -)” # 这会将 rbenv 相关设置添加到当前 shell
然后再执行你的命令,例如
nvm use 16
bundle exec fastlane …
``
PATH` 设置。检查它是否包含了必要的路径。
这确保了脚本在执行后续命令前,工具链的环境已经正确配置。
* **检查 Xcode 的 Build Settings 中的 PATH:** 虽然不常见,但有时项目或 Target 的 Build Settings 中会有一个
- 使用绝对路径: 找到命令的完整路径(使用
4.3. 脚本内容或逻辑错误
脚本本身的错误是最直接的原因。
- 问题: 脚本语法错误、逻辑判断错误、尝试访问不存在的文件/目录、循环错误等。
- 修复:
- 仔细阅读错误日志: 日志通常会指示脚本在哪一行失败。
- 在终端中调试脚本:
- 复制整个脚本内容,粘贴到终端中执行。
- 在脚本开头加上
set -e
,这使得脚本在任何命令返回非零退出码时立即停止执行,帮助你定位失败的具体命令。 - 在脚本开头加上
set -x
,这会在执行每一行命令之前,先打印出该命令及其参数,非常有助于跟踪脚本执行流程和变量值。 - 在脚本的关键位置使用
echo "Executing step X..."
来打印进度信息,确定脚本执行到哪里失败了。 - 使用
ls
,pwd
,cat
等命令在脚本中检查文件是否存在、当前工作目录是否正确、文件内容是否符合预期。
- 检查文件路径: 确保脚本中使用的相对路径或绝对路径是正确的。记住,脚本的当前工作目录通常是你的项目根目录,但有些工具可能会改变工作目录。使用
pwd
命令可以查看脚本执行时的当前目录。 - 检查脚本权限: 确保脚本文件本身具有执行权限 (
chmod +x your_script.sh
)。
4.4. 第三方工具问题 (SwiftLint, Fastlane, etc.)
当脚本只是一个调用第三方工具的包装时,问题可能出在工具本身。
- 问题: 工具未安装、版本不兼容、配置文件错误、工具执行过程中遇到内部错误。
- 修复:
- 在终端中独立运行工具: 找到脚本中调用该工具的那一行命令,在终端中(从项目根目录或脚本实际执行的目录)独立执行它。这样可以看到工具完整的输出和错误信息。
- 检查工具安装: 确保工具已正确安装。如果是通过 Homebrew 安装 (
brew install swiftlint
),确保 brew 环境正常;如果是通过 RubyGems 安装 (gem install fastlane
),确保 Ruby 环境和 gem 环境正常;如果是通过 npm/yarn 安装,确保 Node.js 环境正常。 - 检查工具版本: 有些项目依赖特定版本的工具。确保你安装的版本符合要求。可能需要升级 (
brew upgrade swiftlint
,gem update fastlane
) 或降级工具。对于 Ruby 工具,考虑使用 Bundler (bundle install
,bundle exec fastlane
) 来锁定和管理工具版本。 - 检查工具配置文件: 大多数这类工具依赖项目中的配置文件(如
.swiftlint.yml
,Fastfile
). 检查这些文件是否存在,语法是否正确,配置是否符合项目的需求。 - 查看工具文档或社区: 如果工具的错误信息比较具体,查阅该工具的官方文档或搜索相关的社区论坛,看是否有其他人遇到类似问题。
4.5. 文件或目录缺失/位置错误
脚本尝试访问或操作一个不存在的文件或目录。
- 问题: 脚本中引用的文件路径不正确,文件被删除或移动,或者脚本执行时的当前工作目录不是预期的。
- 修复:
- 检查日志中的文件路径: 错误日志通常会包含找不到的文件路径。
- 验证路径: 在终端中使用
ls
命令验证日志中提到的路径是否存在。 - 检查相对路径基准: 如果脚本使用相对路径,确定脚本执行时的当前工作目录是什么(可以在脚本开头加上
pwd
打印出来),然后根据这个目录来修正相对路径。 - 检查文件是否被
.gitignore
忽略: 如果脚本依赖某个本应存在但被忽略的文件,需要调整.gitignore
或手动生成/获取该文件。
4.6. Project 配置问题
有时候问题出在 Xcode 项目本身的配置上。
- 问题: Run Script 阶段配置错误、输入/输出文件列表不正确、脚本执行顺序问题、或者有重复的 Run Script 阶段。
- 修复:
- 检查 Run Script 配置: 在 Project Navigator 中选择你的项目或 Target,进入 Build Phases 选项卡。找到失败的那个 Run Script 阶段。检查:
- 脚本内容本身是否正确。
- Shell 类型是否正确(
/bin/sh
,/bin/bash
,/bin/zsh
等)。 Show environment variables in build log
选项是否勾选(有助于调试环境问题)。Run script only when installing
是否正确设置。Input Files
和Output Files
列表是否正确(如果使用了这些功能,它们可以帮助 Xcode 判断何时需要重新运行脚本)。错误的 Input/Output 配置有时会导致脚本未按预期执行或重复执行。
- 检查 Build Phase 顺序: 确保脚本在它所需的输入文件生成之后、依赖其输出文件的阶段之前执行。例如,一个生成代码的脚本必须在 Compile Sources 之前执行。
- 检查重复脚本: 确保没有意外添加了同一个脚本两次。
- 检查 Run Script 配置: 在 Project Navigator 中选择你的项目或 Target,进入 Build Phases 选项卡。找到失败的那个 Run Script 阶段。检查:
4.7. 签名与 Provisioning Profile 相关(较少见,但可能)
虽然 Run Script 错误通常与脚本逻辑或环境有关,但在某些特定情况下,签名问题可能间接导致脚本失败(例如,某个脚本需要检查应用的签名信息或访问签名相关的资源)。
- 问题: 脚本依赖于正确的签名环境,但签名配置有问题。
- 修复:
- 检查你的项目的签名设置(Signing & Capabilities 选项卡)。
- 确保选择了正确的 Team 和 Provisioning Profile。
- 清理并重新下载有效的 Provisioning Profiles。
- 确保 Keychain Access 中的证书有效。
三、高级调试技巧
除了上述针对性修复,还有一些高级技巧可以帮助你更有效地调试 Run Script 错误:
- 使用
set -e
和set -x
:- 在脚本开头加上
set -e
: 脚本会在任何命令返回非零退出码时立即退出。这比等待整个脚本执行完毕才看到错误信息要高效得多。 - 在脚本开头加上
set -x
: Xcode 会在执行脚本中的每一行命令之前,先打印出该命令及其展开后的参数。这能让你清楚地看到脚本的执行流程和变量的实际值。非常有助于调试复杂的脚本和环境变量问题。 - 在解决问题后,记得将
set -e
和set -x
移除,以免影响构建性能和日志整洁。
- 在脚本开头加上
- 将脚本输出重定向到文件: 如果 Xcode 的构建日志输出被截断或难以阅读,可以将脚本的输出重定向到文件:
bash
#!/bin/bash
exec > "${PROJECT_DIR}/script_output.log" 2>&1
# 你的脚本内容...
# 例如:
# set -e
# set -x
# echo "Starting my script..."
# your_command_that_might_fail arg1 arg2
# echo "Script finished."
这样,脚本的所有标准输出和标准错误都会被写入到项目根目录下的script_output.log
文件中,你可以方便地查看完整的输出。 -
在脚本中检查特定命令的退出码: 如果你想让脚本在某个命令失败时执行特定的操作或打印更详细的信息,可以检查
$?
变量,它包含了上一个执行命令的退出码。
“`bash
#!/bin/bash
# … other script code …your_command_that_might_fail arg1 arg2
COMMAND_EXIT_CODE=$?if [ $COMMAND_EXIT_CODE -ne 0 ]; then
echo “ERROR: ‘your_command_that_might_fail’ failed with exit code $COMMAND_EXIT_CODE”
# 可以在这里添加更多诊断信息
# cat /path/to/some/log/file_from_command
exit $COMMAND_EXIT_CODE # 以失败的退出码退出整个脚本
fi… rest of your script …
“`
这样可以让你更精细地控制脚本的错误处理和输出。
4. 使用硬编码的路径进行测试: 如果怀疑是路径问题,可以暂时在脚本中用硬编码的绝对路径替换变量或相对路径,看看问题是否解决。解决后再恢复并找到正确的动态获取路径的方法。
四、预防措施:减少未来遇到此错误的可能性
- 版本控制工具链: 对于项目中使用的各种命令行工具(SwiftLint, Fastlane, CocoaPods 等),尽量使用版本管理工具(如 Bundler, npm/yarn 的
package.json
, CocoaPods 的Podfile.lock
)来锁定版本,并在构建前确保使用了正确的版本(例如使用bundle exec
执行 Ruby 工具)。 - 标准化环境: 尽量让团队成员的开发环境保持一致,尤其是在使用
brew
,nvm
,rbenv
等工具时。考虑使用asdf
这样的通用版本管理器。 - 清晰的脚本: 编写清晰、易读、有注释的脚本。避免在脚本中硬编码敏感信息或随环境变化的信息。
- Code Review: 将构建脚本纳入代码审查流程,让团队成员互相检查潜在的问题。
- 在 CI 环境中测试: 如果项目使用了持续集成 (CI) 系统,确保你的构建脚本也能在 CI 环境中正常工作,因为 CI 环境可能与本地开发环境有所不同。如果 CI 构建失败,其日志通常也非常有助于诊断问题。
五、总结
Xcode phasescriptexecution failed: nonzero exit code
是一个常见但棘手的错误,因为它是一个通用性的失败指示。解决它的关键在于 不慌乱,有条理。
- 清理: 先尝试基本的清理步骤(Clean Build Folder, DerivedData, 重启)。
- 定位: 利用 Report Navigator 找到 具体 是哪个 Run Script 阶段失败了。
- 分析: 仔细阅读该阶段的构建日志,这是获取错误 原因 的唯一途径。将关键错误信息提取出来。
- 诊断与修复: 根据日志中的错误信息,对照本文提供的常见原因和解决方案,有针对性地进行排查和修复。这可能涉及检查脚本内容、文件权限、环境变量、第三方工具、依赖管理或项目配置。
- 调试: 灵活运用
set -e
,set -x
, 输出重定向等调试技巧来深入了解脚本的执行过程。
记住,耐心和细致是解决这个问题的最佳武器。通过遵循上述步骤,你将能够有效地诊断并修复绝大多数导致 phasescriptexecution failed: nonzero exit code
的问题,让你的 Xcode 构建过程恢复顺畅。