NuShell中运行QEMU无法实现交互式操作的解决方案咨询
背景情况
我最近碰到个闹心的问题:QEMU有个特别好用的功能,能把它的标准IO流连接到虚拟机的串口上,这样就能像SSH会话一样和虚拟机里的TTY shell交互。但我用NuShell运行的时候,它好像会对输出做缓冲处理,结果就是完全没法和虚拟机互动——所有输出都要等QEMU关掉之后才一次性弹出来,包括我之前在那个没反应的shell里敲的所有内容。
有意思的是,同样的命令放到Bash里运行(哪怕是从NuShell里用bash -c调用Bash来执行),就能正常使用交互式shell,完全没缓冲问题。
我的需求
我想在NuShell里搞定这个事儿,虽然对TTY和管道输出的差异了解不多,但明显Bash和NuShell对标准IO流的处理逻辑不一样。我希望能找到一个解决方案,要么让NuShell停止缓冲QEMU的输出,要么通过某个工具中转一下,让它表现得像Bash那样不做缓冲。
可能的解决办法
用
exec直接转交终端控制权
NuShell的exec命令会让当前shell把终端的完全控制权交给QEMU,跳过中间的缓冲环节。试试这样运行你的QEMU命令:exec qemu-system-x86_64 [你的QEMU启动参数] -serial stdio这个操作相当于让QEMU直接接管你的终端,和在Bash里直接运行的效果几乎一致。
借助
unbuffer工具模拟无缓冲TTY环境
如果你的系统安装了expect工具包(通常会附带unbuffer),可以用它来包装QEMU命令,强制输出无缓冲:unbuffer qemu-system-x86_64 [你的QEMU启动参数] -serial stdiounbuffer会创建一个伪TTY,让QEMU误以为自己在交互式终端中运行,从而自动禁用缓冲机制。调整QEMU的串口参数
试试把QEMU的串口参数改成-serial mon:stdio,这个参数会把标准IO同时作为QEMU的监控器和虚拟机串口,有时候能绕过NuShell的缓冲问题:qemu-system-x86_64 [你的QEMU启动参数] -serial mon:stdio另外,也可以先设置终端类型的环境变量,再运行QEMU:
export TERM=xterm qemu-system-x86_64 [你的QEMU启动参数] -serial stdio尝试用
nu -c直接执行命令
虽然你提到用bash -c可行,但也可以试试用NuShell自身的-c参数来运行单条命令:nu -c "qemu-system-x86_64 [你的QEMU启动参数] -serial stdio"这种方式有时候会让NuShell以更接近原生的方式处理IO,减少不必要的缓冲。
备注:内容来源于stack exchange,提问作者J-Cake

