You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Git Bash命令替换后read立即返回EOF 但Cygwin运行正常

Git Bash环境下命令替换后首个read命令立即触发EOF问题

问题背景

  • 开发了一款用于在Git Bash中生成代码diff的bash辅助脚本,脚本中调用自研程序menu实现交互选择:
    • menu接收命令行参数传入的选项列表(本次场景下选项为Git提交记录),提示用户完成选择
    • 脚本通过命令替换方式调用menu,调用形式如下:
      commit=$(menu --title "Choose a commit:" "CommitA" "CommitB" "CommitC")
      
    • menu内部通过fgets(line, 256, stdin);读取用户输入的选择,所有选项列表输出到stderr,避免被命令替换捕获;用户选定的结果输出到stdout供命令替换捕获(后续最小复现样例中省略了向stdout输出结果的逻辑,该逻辑不会影响后续read命令的行为)
  • 命令替换执行完成后,脚本通过bash内置read命令提示用户输入输出目录:
    read -p "Enter the output directory: " outputDir
    
  • 上述逻辑在Cygwin环境下运行完全正常,但在Git Bash环境中运行时,read命令会立即触发EOF,不会等待用户输入文本。

最小复现样例

由于menu程序代码量较大不便完整展示,构造了名为prompt的极简C程序替代menu,仅向stderr输出简单提示后调用fgets读取输入,模拟menu的核心行为,对应的测试脚本和C代码如下:

> cat test.sh
x=$(./prompt)
read -p "read> " x

> cat prompt.c
#include <stdio.h>

int main(int argc, char **argv)
{
   char line[256];

   fprintf(stderr, "fgets> ");
   fflush(stderr);
   fgets(line, 256, stdin);

   return 0;
}

跨环境运行差异

不同环境下运行测试脚本的结果存在明显差异:

  • Cygwin环境运行结果:
    > ./test.sh
    fgets> foo
    read> bar
    
  • Git Bash环境运行结果:
    > ./test.sh
    fgets> foo
    read>       # <== read立即返回,不等待用户输入
    

初步排查与临时方案

  • 最初猜测是命令替换执行后stdin缓冲区残留字符,但执行echo -n "$x" | wc -c返回0,证明没有读取到残留输入。
  • 进一步测试发现,该异常仅出现在命令替换后的第一个read调用,后续的read可正常工作:如果在命令替换后新增一个空的占位read,Git Bash下后续的read即可正常等待输入:
    > cat test.sh
    x=$(./prompt)
    # 占位read用于清空stdin
    read
    # 该read在Git Bash下可正常工作
    read -p "read> " x
    
  • 目前找到的临时规避方案:为占位read添加-t 0.1的超时参数,即可消耗stdin中多余的EOF,无需用户额外按回车即可跳过占位read:
    x=$(./prompt)
    # 带超时的占位read
    read -t 0.1
    read -p "read> " x
    
    该方案属于临时规避手段,理论上无需添加占位read脚本即可正常运行。

涉及环境版本信息

  • Cygwin环境:bash版本为4.4.12(3)-release (x86_64-unknown-cygwin),运行正常
  • Git Bash环境:bash版本为4.4.23(1)-release (x86_64-pc-msys),存在上述异常
  • Ubuntu 20.04环境(bash 5.0.17):运行正常

内容的提问来源于stack exchange,提问作者Mike Holt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 09:03:33