真正跨平台的自动化任务应使用 PHP 脚本统一处理环境判断与命令执行,避免在 Composer scripts 中直接写 shell 命令;因 Linux/macOS 用 /bin/sh、Windows 默认用 CMD,语法和命令行为差异大,易导致静默失败;推荐通过 @php 调用 PHP 脚本,用 PHP_OS_FAMILY 判断系统,proc_open() 或标准函数执行操作。

不支持直接跨平台命令,但可以通过 PHP 脚本中转实现真正通用的自动化任务。 Composer 的 scripts 字段本身只是字符串命令注册表,底层执行器随系统切换(Linux/macOS 用 /bin/sh,Windows 默认用 CMD),导致 &&、[ ]、路径分隔符、命令名等处处踩坑。硬塞 shell 条件判断只会让脚本在某个平台跑通,在另一个平台静默失败或报错。
为什么 scripts 里写 if [ "$OSTYPE" = "linux" ]; then ... fi 会炸
这类 shell 片段在 Windows CMD 下根本无法解析——CMD 不认识方括号语法,也不支持 $OSTYPE 变量;即使你在 Git Bash 里运行 composer run,Composer 仍可能调用 CMD 执行脚本,导致整个命令被当做一个文件名报 “'[' is not recognized”。更隐蔽的是,find、rm、sed 等命令在不同系统上行为差异极大,且 exit code 含义不一致,条件链极易断裂。
- Linux/macOS:默认走
/bin/sh,支持 POSIX shell 语法 - Windows:默认走 CMD,仅支持极简批处理逻辑;PowerShell 需显式指定,且引号/空格解析规则完全不同
- 所有平台都认
@php前缀:它会自动使用 Composer 绑定的 PHP 版本,并保持工作目录为项目根
正确做法:用 PHP 脚本做唯一入口,统一判断环境
把平台判断、路径拼接、命令执行全部收口到一个 PHP 文件里,比如 scripts/run-task.php,然后在 composer.json 中只写一条干净调用:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
"scripts": {
"build:assets": "php scripts/run-task.php build"
}
脚本内用原生 PHP 做决策,稳定可靠:
- 用
PHP_OS_FAMILY(PHP 7.2+)判断系统,值恒为"Linux"、"Windows"或"Darwin" - 检查扩展是否真实可用:
extension_loaded('posix'),而非依赖config.platform声明 - 调用系统命令时,优先用
proc_open()并传入完整路径,或用exec('which node 2>/dev/null')动态查找 - 清理缓存、复制文件、设置权限等操作,全部用 PHP 标准函数(
unlink()、copy()、chmod())替代 shell 命令
如果非要用纯 JSON 配置,只能靠 platform + CI 分发兜底
某些 CI 场景(如 GitHub Actions)可预设运行平台,这时可配合 config.platform 和环境变量做有限适配,但这不适用于本地开发或任意宿主环境:
-
"config": { "platform": { "php": "8.2.0" } }只影响依赖解析,不改变实际执行行为 - CI 中可用
if: runner.os == 'Windows'分发不同 script 条目,但这是 CI 工具能力,不是 Composer 能力 - 坚持在
scripts里写双命令数组(如["del /q build\*", "mkdir build"]和["rm -rf build/", "mkdir build"])会导致维护成本飙升,且无法共享逻辑
真正跨平台的脚本,从来不是靠猜系统类型来拼命令,而是用 PHP 把“做什么”和“怎么做”彻底解耦——判断交给 PHP,执行也交给 PHP,只留最薄一层 composer run 做触发入口。否则,你写的不是自动化脚本,是给每个平台准备的一套兼容性补丁。

















