使用agetty创建的ttyGS0终端中Bash read命令回车异常求助
我之前在initramfs里折腾USB gadget串口时也碰到过一模一样的问题!核心原因就是终端的行结束符映射没配置对:Enter键发送的是CR(\r,也就是Ctrl+M),但bash的read命令默认只认LF(\n,Ctrl+J),而ttyGS0在initramfs的极简环境里没自动做好CR到LF的转换。下面是几个亲测有效的修复方案:
方案1:给agetty加--crnl启动参数
最直接的办法是在启动agetty时指定行结束符转换规则,--crnl参数会强制把输入的CR转换成LF,同时输出时把LF转换成CR+LF,完美适配终端的输入输出逻辑。
修改你initramfs里的agetty启动命令,改成这样:
agetty --crnl 115200 ttyGS0 bash
重启agetty之后,按Enter应该就能正常触发read命令了。
方案2:bash启动后立刻修正stty配置
如果没法修改agetty的启动参数,也可以在bash初始化时手动打开icrnl选项——这个选项的作用就是自动把输入的CR转换成LF。
你可以在initramfs里的bash启动脚本(比如.bashrc,或者直接在启动bash的命令后面追加)加上这条命令:
stty icrnl
执行后终端就会自动处理Enter键的CR信号,read命令就能正常响应了。
方案3:检查USB gadget驱动的内核参数
ttyGS0是USB gadget串口设备,部分内核版本的gadget驱动可能默认关闭了CR/LF转换。你可以尝试加载驱动时指定相关参数,比如如果用的是g_serial模块:
modprobe g_serial crnl=1
不过这个得看你的内核版本是否支持这个参数,不同版本的gadget驱动参数可能有差异,需要自己测试下。
方案4:临时修改read的换行符识别(应急用)
如果上面的方案都没法快速生效,也可以临时修改单个read命令的换行符识别,通过调整IFS环境变量让read认CR:
IFS=$'\r\n' read -p "请输入内容: " var
但这个方案只对单个read命令生效,全局修改IFS可能会影响其他命令的正常运行,所以只推荐应急时用。
内容的提问来源于stack exchange,提问作者Linh Hoàng

