我正在try 用Rust编写一个程序,将字符串写入一个命名的管道.然而,数据只在程序退出后才会显示在接收端.

下面是我的代码:

use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::Write;
use std::fs::{File, OpenOptions};

fn send_data(file: &mut File, payload: &str) -> Result<(), std::io::Error> {
    file.write(payload.as_bytes()).unwrap();
    // I tried file.write_all() and file.flush(); same result
    Ok(())
}

fn main() {
    let mut file = OpenOptions::new()
        .write(true)
        .open("/tmp/my_named_pipe")
        .expect("Failed to open named pipe for writing");

    let mut stdout = std::io::stdout().into_raw_mode().unwrap();
    stdout.flush().unwrap();

    loop {
        let key = match std::io::stdin().keys().next() {
            Some(Ok(input)) => input,
            _ => break,
        };
        match key { // press x to send data, q to quit
            Key::Char('q') => break,
            Key::Char('x') => send_data(&mut file, "foobar").unwrap(),
            _ => (),
        }
    }
}

我正在创建一个带有mkfifo /tmp/my_named_pipe的命名管道,然后用tail -f /tmp/my_named_pipe开始监听它.然后,在另一个终端窗口中,我运行我的程序(并按下"x"几次)."尾—f"什么都没显示.当我退出我的程序(通过按'q')所有字符串显示一次.

我希望每个按键都能调用send_data(),每个调用都能立即在tail -f侧呈现.如何做到这一点?

推荐答案

正如所建议的,这里是我的 comments 稍微发展的回答.

The problem does not stand on the Rust side, but on the tail -f side.
After creating the pipe with mkfifo /tmp/my_named_pipe, we can start a producer with:

( while true; do echo -n X ; sleep 1 ; done ) >/tmp/my_named_pipe

这会每秒向管道中写入一个X,不带新行.

In another terminal, trying to consume the pipe with tail -f /tmp/my_named_pipe does not show anything till the producer is stopped.
This is the problem reported in the question.
If we replace echo -n X with echo X (i.e. we generate a new-line each time), in the producer, this does not change anything in the consumer.
Then, the problem is not related to tail waiting for a line before outputting anything; it's probably due to the way it watches a pipe (I did not take the time to study the source code).

However, trying to consume the pipe with dd if=/tmp/my_named_pipe bs=1 or simply cat /tmp/my_named_pipe shows an X every second, even without new-line.
This confirms that the problem is due to tail.

Rust相关问答推荐

如何从polars DataFrame中获取一个列作为Option String?<>

什么是Rust惯用的方式来使特征向量具有单个向量项的别名?

防止cargo test 中的竞争条件

替换可变引用中的字符串会泄漏内存吗?

在我的Cargo 中,当我在建筑物中使用时,找不到我可以在产品包中使用的 crate .r我如何解决这个问题?

JSON5中的变量类型(serde)

在什么情况下 `..._or()` 比 `..._or_else(|| {})` 更好,为什么?

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

提取指向特征函数的原始指针

为什么这个闭包没有实现Fn?

如何为已实现其他相关 std trait 的每个类型实现一个 std Trait

缺失serde的字段无法设置为默认值

为什么需要同时为值和引用实现`From`?方法不应该自动解引用或borrow 吗?(2023-06-16)

Rust 中 Mutex<> 的深拷贝?

如何在 Rust 中将 UTF-8 十六进制值转换为 char?

如何在 Rust 中返回通用 struct

从 Cranelift 发出 ASM

为什么这个值在上次使用后没有下降?

如何在 Rust 的内置函数上实现特征?

如何在 Rust 的泛型函​​数中同时使用非拥有迭代器和消费迭代器?