不能。Composer 的 run-script 命令仅执行 scripts 中定义的键名,不直接运行 .sh 或 .bat 文件;需显式调用 sh -c、cmd /c 或用 PHP 封装以确保跨平台兼容与安全执行。
run-script 能否直接执行 .sh 或 .bat 文件?
不能。Composer 的
命令只识别
部分定义的键名,它本身不解析或执行任意外部文件路径。你写
,Composer 会尝试把
当作 PHP 脚本去加载(失败),而不是交给 shell 执行。
正确做法:用 shell 命令包装脚本路径
必须显式调用
、
或
,让系统真正启动解释器。Windows 和 Linux 行为不同,需分开处理:
Linux/
mac
OS 下推荐用
包裹,避免 shebang 解析异常或权限问题
Windows 下需用
,且注意反斜杠转义和空格路径
跨平台项目建议统一用
中转(见下一点),否则 CI/CD 容易因环境差异失败
为什么推荐用 PHP 封装 Shell 调用?
绕过平台差异和 Composer 对命令格式的限制,同时能做前置检查、错误捕获和路径标准化:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
/
不会自动继承 Composer 的工作目录,需用
或
显式拼接
返回值需手动判断:
中
才算失败
敏感字符(如空格、括号)必须用
处理,否则脚本名含空格会中断执行
常见失败原因和验证步骤
执行
报错时,先排除这几个硬性条件:
脚本文件没有可执行权限(Linux/macOS):
Windows 上用了 Unix 风格换行(LF),导致
解析失败 —— 用
或编辑器转 CRLF
中脚本定义末尾多了逗号(JSON 语法错误),导致整个
段被忽略
脚本里用了相对路径(如
),但执行时工作目录不是预期位置 —— 建议全部改用
或 PHP 的
最稳妥的验证方式:先手动运行
,确认它在终端里能成功,再放进
。
run-scriptscripts"scripts": {"build": "./build.sh"}./build.shshbashcmdsh -ccmd /cphp"scripts": {
"build": "sh -c './build.sh'",
"test-win": "cmd /c build.bat",
"lint": "sh -c 'find src -name "*.php" | xargs php -l'"
}exec()shell_exec()getcwd()__DIR__exec($cmd, $output, $returnCode)$returnCode !== 0escapeshellarg()"scripts": {
"deploy": "php -r "chdir(__DIR__); exec(escapeshellarg('./deploy.sh') . ' 2>&1', $out, $code); if ($code !== 0) { echo implode("\n", $out); exit($code); }""
}composer run-script xxxchmod +x ./build.shcmddos2unixcomposer.jsonscripts../config/app.yml$(dirname $0)/..__DIR__sh -c './build.sh'composer.json