linux/macos下vendor/bin脚本permission denied,根本原因是zip/git不保留unix执行位,需chmod +x vendor/bin/*临时修复,或在composer.json中配置post-install-cmd自动补权,windows用户应改用php vendor/bin/phpunit调用。

vendor/bin/脚本在Linux/macOS上Permission denied怎么办
不是脚本写错了,是文件缺少可执行位。Composer从ZIP或Git拉取代码时,Unix权限不会被保留,vendor/bin/phpunit这类文件默认无x权限。
- 临时修复:运行
chmod +x vendor/bin/*(仅当前项目有效) - 长期方案:在
composer.json的scripts里加"post-install-cmd": "chmod +x vendor/bin/*"——注意该命令在Windows下会被Composer自动跳过,安全 - 根本解法:让包作者在Git仓库中对
bin/下文件执行git update-index --chmod=+x bin/phpunit,确保检出即带x位
Windows上vendor/bin/脚本直接报“不是内部或外部命令”
这不是权限问题,是执行机制不兼容。Windows不识别#!/usr/bin/env php,且Composer不会自动为Unix风格脚本生成.bat包装器——这事得包作者自己做。
- 别直接运行
vendor/bin/phpunit,改用php vendor/bin/phpunit - 跨平台CI/脚本中,统一用
php前缀调用,例如在composer.json里定义"test": "php vendor/bin/phpunit" - 若依赖的包(如
symfony/console)自带.bat入口,才可直接调用;否则不要假设它存在
composer install在不同系统解析出不同版本包
Composer本身不按系统选包,差异来自require中声明的扩展(如ext-posix)或config.platform配置是否生效。
- 错误典型表现:
Your requirements could not be resolved... ext-posix * but it is missing - 定位来源:
composer show --tree | grep posix,看哪个包引入了该约束 - 修复方向:把
"ext-posix": "*"从require移到require-dev,或改用if (function_exists('posix_getpid')) { ... }运行时判断 -
config.platform必须写在composer.json根对象的config字段下,例如:"config": { "platform": { "php": "8.2.12", "ext-gd": "8.2.12" } }——它只影响composer update时的依赖解析,install用的是已锁的composer.lock
全局镜像配置在各系统上静默失效的常见原因
配了但没生效,大概率是命令漏要素、路径错、或没重启终端——尤其Windows下,PowerShell/CMD不重载%APPDATA%\Composer\config.json。
- Windows必须重启终端才能使
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/生效 - Linux/macOS切忌
sudo composer config -g,否则配置写进root家目录,普通用户读不到;验证用ls -l ~/.composer/config.json - Git Bash易把
~/.composer解析错,直接打开%APPDATA%\Composer\config.json(Win)或~/.composer/config.json(macOS/Linux)确认内容 - 末尾斜杠
/不能省:https://mirrors.aliyun.com/composer/✅,https://mirrors.aliyun.com/composer❌(拼接失败)
实际部署中最容易被忽略的点是:你本地composer.lock是在macOS上生成的,里面记录的依赖分支可能依赖ext-pcntl,而CI跑在Linux容器里却没显式声明config.platform,结果install阶段一切正常,运行时才爆Function pcntl_fork not found——这种延迟暴露的问题,比安装失败更难排查。











