composer脚本不自动拦截stdin,是否交互由代码决定;需用posix_isatty(stdin)判断tty环境,结合composer_no_interaction等变量控制交互逻辑,ci中应避免阻塞式输入。

Composer脚本本身不拦截 stdin,但可以主动读取
Composer 不会自动捕获或阻止脚本里的 fgets(STDIN) 或 readline(),也就是说:脚本是否交互,完全取决于你写的代码。它既不会帮你弹出提示,也不会替你跳过输入——你写一行 fgets(STDIN),它就真等在那里。
但要注意,这行为只在终端是 TTY 时可靠。CI 环境、Docker 容器没加 -t、或命令被管道重定向(如 composer install | grep),posix_isatty(STDIN) 就会返回 false,fgets 直接返回 false 或空字符串,脚本可能意外跳过或报错。
- 必须先判断环境:
if (posix_isatty(STDIN)) { $input = fgets(STDIN); } - 别假设用户一定输入了内容,
trim($input)后还得检查是否为空 - 在非 TTY 下,应提供合理默认值(比如
$host = $_ENV['DB_HOST'] ?? 'localhost';)
post-install-cmd 脚本里怎么安全提问
很多包用 post-install-cmd 做初始化配置,比如生成密钥、选数据库驱动。这类脚本一旦写死 ask(),就会在 CI 中卡住。真正安全的做法是让脚本自己决定是否交互。
- 用
Symfony\Component\Console\Input\InputInterface的isInteractive()方法判断(前提是脚本基于 Console 组件) - 不依赖 Console?直接查环境变量:
getenv('COMPOSER_NO_INTERACTION') === '1'或$_SERVER['COMPOSER_NO_INTERACTION'] ?? false - 避免只靠
--no-interaction参数:某些插件或自定义安装器根本不读这个,必须双保险——既检查参数,也查环境变量 - 示例逻辑:
if (!$io->isInteractive() || !posix_isatty(STDIN)) { return $this->useDefaults(); }
环境变量比交互更可靠,但得按包约定来
没有统一标准,每个包对环境变量的命名和行为都不同。强行猜 SKIP_SETUP 或 NO_PROMPT 很容易失效。
正确做法是:先看包的文档或源码里 post-install-cmd 脚本,找 getenv()、$_ENV 或 $_SERVER 的调用点。常见模式有:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
ACCEPT_LICENSE=1(绕过许可证确认) -
APP_KEY=base64:xxx(预设 Laravel 密钥) -
DB_CONNECTION=sqlite(跳过数据库类型选择) -
CONFIG_FILE=app.yaml(指定配置路径,避免提问)
如果找不到明确支持的变量,最稳妥的方式是临时删掉或注释掉该脚本——在 composer.json 里覆盖为:"post-install-cmd": ["echo 'Skipped interactive setup'"]。
本地调试时 --interactive 没用,得用真实终端
composer install --interactive 不会让脚本变成交互式,它只影响 Composer 自身的少数确认点(比如删 vendor、信源验证)。你自己写的脚本,哪怕加了 --interactive,照样不会多出一个提示框。
调试交互逻辑时,唯一有效方式是:
- 确保在真实终端运行(不是 VS Code 内置终端未启用 TTY,或 Docker run 没加
-t) - 不要用
bash -c "composer install"这类包装,会截断STDIN - 检查
php_sapi_name()是cli,且posix_isatty(STDIN)返回true - 在脚本开头加
var_dump(posix_isatty(STDIN), stream_get_meta_data(STDIN));快速定位阻塞点
自动化流程中交互永远是个妥协点:要么接受人工介入,要么把所有分支逻辑收束到环境变量和配置文件里。没人会去修一个在 CI 里卡住五分钟的 post-install-cmd,但所有人都会立刻改环境变量。










