镜像源解压dist包时丢弃chmod+x位导致vendor/bin脚本无执行权限;ls -l显示-rw-r--r--即可确认,因阿里云等镜像用--no-same-permissions强制设644权限,而packagist.org保留原始x位。

镜像下载后 vendor/bin 脚本无执行权限,是阿里云、腾讯云等国内镜像源在解压 dist 包时丢弃了原始 chmod +x 位导致的,不是你本地环境或 Composer 本身的错。
为什么 ls -l vendor/bin/phpunit 显示 -rw-r--r-- 就一定是镜像问题
官方 packagist.org 的 dist tar 包保留了可执行位,但部分镜像(如旧版阿里云)用 tar --no-same-permissions 或 --no-symlinks 解包,强制重设所有文件权限为 644;
现象是:./vendor/bin/phpunit 报 Permission denied,而 php vendor/bin/phpunit 可正常运行;
验证命令:ls -l vendor/bin/phpunit —— 若无 x 位,且你没手动改过权限,基本可锁定为镜像源行为。
临时修复:chmod +x vendor/bin/* 为什么不能直接上 CI
这条命令能立刻恢复功能,但有隐患:
• 它会把非脚本文件(比如 vendor/bin/README 或空文件)也设成可执行,部分 CI 工具(如 GitLab Runner)会警告甚至失败;
• 不区分文件类型,可能覆盖掉某些包本意设为不可执行的二进制资源;
• 每次都要手动跑,治标不治本;
推荐只在调试或本地应急时用:chmod +x vendor/bin/* 2>/dev/null || true。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
post-install-cmd 自动补权限时,为什么必须用 is_executable() 判断
Composer 不会自动还原执行位,但你可以用钩子精准补。关键逻辑是只对“本该可执行却不可执行”的文件操作:
• is_executable($f) 判断当前是否已具备执行能力,避免重复 chmod;
• chmod($f, 0755) 显式设权,不依赖 umask;
• 脚本只扫 vendor/bin/*,不递归、不碰其他目录;
Windows 下该脚本无效,需单独处理(比如用 PowerShell 脚本或跳过);
示例片段:"@php -r \"if(is_dir('vendor/bin')) {\$files=glob('vendor/bin/*');foreach(\$files as \$f) {if(is_executable(\$f))continue;chmod(\$f, 0755); } }\""。
切镜像源后 vendor 权限突然错乱,根本原因不是缓存而是打包策略差异
不同镜像对 dist 包的二次处理方式不一致:
• 阿里云某版本默认启用 --no-same-permissions;
• 腾讯云曾默认加 --no-symlinks,连带影响权限继承;
• 清华源等较新镜像已修复此问题,但切换后旧 vendor 目录不会自动修正;
所以不要指望换源后权限自动恢复——必须删掉 vendor/ 和 composer.lock 重装,否则残留的 644 文件会一直卡住脚本执行。
真正麻烦的是:这个问题不报错、不中断安装流程,只在你第一次想运行 ./vendor/bin/xxx 时才暴露,而且错误信息极其模糊。它藏在镜像源的构建链路里,你查不到日志,也看不到 warning,只能靠 ls -l 手动确认。










