答案是加--verbose参数可显示真实错误;因composer默认静默吞掉stderr,需在脚本中显式输出错误、避免异常被静默捕获,并确保不重定向stderr到/dev/null。

Composer脚本执行失败时,exit code 不为0 但没报错信息?
默认情况下,Composer 执行自定义脚本(如 scripts 中定义的 post-install-cmd)时,若脚本本身出错但未显式输出错误,你只会看到类似 Script xxx handling the xxx event returned with error code 1,没有堆栈或 stderr 内容。这是因为 Composer 默认不透传子进程的 stderr,尤其当脚本是 PHP 文件或调用其他命令时。
解决的关键是让错误流“漏出来”。常见做法不是改 Composer 配置,而是从脚本自身入手:
- PHP 脚本中主动捕获异常并
echo或error_log(..., 4)到STDERR - Shell 类脚本(如
bash)结尾加2>&1显式重定向 stderr 到 stdout - 避免在脚本里静默吞掉异常 —— 比如
try { ... } catch (\Exception $e) { }且不打印,等于把错误藏进黑洞
启用 Composer 的 -v 或 --verbose 参数真能看 stderr 吗?
能,但有前提:它只对 Composer 自身执行逻辑和部分内置命令(如 install、update)生效,对用户定义的 scripts 中调用的外部命令(比如 php foo.php 或 npm run build)默认仍不透传其 stderr,除非该命令自己支持 verbose 模式。
所以 composer install -v 可能显示 “Running script xxx…” 和返回码,但不会自动 dump 出 xxx 脚本内部的 var_dump() 或未捕获的 Warning。验证方式很简单:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
composer run-script my-test-script -v
如果脚本里写了 trigger_error("oops", E_USER_WARNING); 却没看到输出,说明它被压住了 —— 这时候就得靠下一条方法。
如何在脚本中可靠重定向 stdout 和 stderr?
最稳妥的方式是在脚本启动阶段就接管输出流,而不是依赖外部参数。不同语言处理方式不同:
- PHP 脚本开头加:
ini_set('display_errors', '1'); error_reporting(E_ALL); fwrite(STDERR, "debug: start\n"); - Bash 脚本第一行写:
exec 2>&1(把所有 stderr 重定向到 stdout,确保 Composer 能捕获) - Node.js 脚本中避免只用
console.log,错误必须走console.error,且不要被try/catch吞掉后不 re-throw - 如果脚本是通过
"scripts": {"foo": "php script.php > /dev/null"}这样写的,立刻删掉重定向 —— 它会直接吃掉所有输出,包括错误
composer.json 里的 process-timeout 和输出捕获有关吗?
无关。process-timeout 控制的是单个外部命令(如 git clone)的最大运行时间,超时后直接 kill 进程并返回非零退出码,但不会影响 stderr 是否可见。它常被误认为“能让错误更早暴露”,其实只是防止卡死;真正影响调试体验的是输出流是否畅通。
容易忽略的一点是:某些 CI 环境(如 GitHub Actions)默认关闭 TTY,导致部分命令(如 php -l 或某些交互式工具)静默失败。这时需显式加 -n(no-interactive)或检查是否意外触发了需要 stdin 的逻辑。










