【问题标题】:How to block stdin for a child process and ignore its stdout?如何阻止子进程的标准输入并忽略其标准输出?
【发布时间】:2020-10-28 21:47:23
【问题描述】:

我正在尝试使用 Rust 构建一个使用 mpv 播放器的 YouTube 流媒体。我已经成功地从 YouTube 搜索页面中提取了音乐视频的 URL。

我已经设置了一个输入循环来接收用户的命令。根据用户命令采取行动。当用户指定play thisSong 时,音乐视频的 URL 被提取并保存为字符串。现在,我想通过调用 mpv player 来启动一个进程。 mpv 播放器的输出应该被忽略,播放器应该在后台播放音乐,用户应该回到提示符,从那里他可以再次提供命令。

我试图设置它,但问题是一旦mpv 子进程启动,它就会开始接受用户提供的命令给我的main 程序。我希望mpv 忽略这些命令。

let mut youtube_mpv = match Command::new("mpv")
        .arg(song_url)
        .arg("--no-video")
        .arg("--ytdl-format=worst")
        .arg("--really-quiet")
        .arg("&")
        .stdout(Stdio::null())
        .spawn()
{
    Err(_why) => exit(1),
    Ok(process) => process,
};

println!("Playing {} from YouTube", song_name);

【问题讨论】:

    标签: rust


    【解决方案1】:

    添加.stdin(Stdio::null())

    默认情况下,子进程将继承父进程的所有流。如果你不想这样,可以pipe他们(通过stdin/stdout与子进程交互)或null他们(重定向到/从/dev/null)。

    顺便说一句,我不这么认为:

    .arg("&")
    

    有任何意义。它会将& 参数传递给mpv,mpv 将假定它是一个文件,查找,找不到,并触发错误。假设你最终在 mpv 子进程上wait(),它总是会报告失败。

    【讨论】:

    • 感谢您对& 的评论。很多人没有意识到这只是 shell 在分析命令行时的文本约定,而这并没有最终进入底层的execve() 系统调用。
    • @prog-fh 我将其称为运算符而不是约定(这也是how opengroup defines it),但是是的。
    猜你喜欢
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多