【问题标题】:How to simulate a TTY while also piping stdio?如何在管道 stdio 的同时模拟 TTY?
【发布时间】:2020-10-22 09:37:28
【问题描述】:

我正在寻找一种跨平台解决方案,用于在 Rust 中模拟 TTY(PTY?),同时还管道 stdio。

前端基于显示交互式终端的网络技术。用户可以运行命令,他们的所有输入都将被发送到 Rust 后端,命令在那里被执行。 Std{in,out,err} 被向后发送以提供交互式体验。

这是一个简化的示例(仅管道标准输出):

let mut child = Command::new(command)
    .stdout(Stdio::piped())
    .spawn()
    .expect("Command failed to start");

loop {
    let read = reader.read(&mut chunk);

    if let Ok(len) = read {
        if len == 0 {
            break;
        }
        let chunk = &chunk[..len];

        send_chunk(chunk); // send chunk to frontend
    } else {
        eprintln!("Err: {}", read.unwrap_err());
    }
}

目前,运行命令tty 打印:not a tty,但理想情况下,它应该输出一个文件名(例如/dev/ttys002)。而程序,例如atty 应该返回true

仅在终端中运行后端,继承了 stdio 的作品,但是我无法将 stdio 发送回前端。

【问题讨论】:

    标签: shell terminal rust tty pty


    【解决方案1】:

    定义“跨平台”。就 PTY 而言,它们是内核支持的伪设备,包括 ioctl 和所有内容。事实上,您的终端仿真器必须做的很多事情就是实现这些 ioctl 的接收端。

    只要您使用的是带有 BSD API(包括 Linux)的机器,最好的做法就是 openpty 并继续使用它。如果您想移植到不支持 BSD PTY 的系统,则必须在子进程中挂钩 tty 函数(通过预加载帮助程序库)。

    【讨论】:

    • 我想支持 Linux、Mac OS、Windows。 BSD PTY 现在支持很好。也许可以通过ConPTY 实现 Windows 支持?
    • 我也在尝试创建一个自定义提示,这是否可能或者这些 ioctl 是否也捆绑了提示?
    • @MartonLanga:提示符是外壳的一部分。只需在您的 PTY 中启动一个 shell 即可。
    • 我也在写一个自定义的shell,所以我想我可以手动处理提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    相关资源
    最近更新 更多