gpt4 book ai didi

unix - 通过将 ctrl-c 发送到标准输入来将 SIGINT 发送到进程

转载 作者:行者123 更新时间:2023-11-29 08:08:40 26 4
gpt4 key购买 nike

我正在寻找一种模仿终端进行某些自动化测试的方法:即启动一个进程,然后通过将数据发送到标准输入并从标准输出读取数据来与其交互。例如。向 stdin 发送一些输入行,包括 ctrl-cctrl-\,这将导致向进程发送信号。

使用 std::process::Commandnd 我可以将输入发送到例如cat 并且我也在 stdout 上看到它的输出,但是发送 ctrl-c(如 I understand that is 3 )不会导致 SIGINT 发送到贝壳。例如。这个程序应该终止:

use std::process::{Command, Stdio};
use std::io::Write;

fn main() {
let mut child = Command::new("sh")
.arg("-c").arg("-i").arg("cat")
.stdin(Stdio::piped())
.spawn().unwrap();
let mut stdin = child.stdin.take().unwrap();
stdin.write(&[3]).expect("cannot send ctrl-c");
child.wait();
}

我怀疑问题在于发送 ctrl-c 需要一些 tty 并且通过 sh -i 它仅处于“交互模式”。

我是否需要完全成熟并使用例如termionncurses

更新:我在最初的问题中混淆了 shell 和终端。我现在把它弄清楚了。我还提到了 ssh,它应该是 sh

最佳答案

最简单的方式就是直接给子进程发送SIGINT信号。这可以使用 nix 轻松完成的 signal::kill 函数:

// add `nix = "0.15.0"` to your Cargo.toml
use std::process::{Command, Stdio};
use std::io::Write;

fn main() {
// spawn child process
let mut child = Command::new("cat")
.stdin(Stdio::piped())
.spawn().unwrap();

// send "echo\n" to child's stdin
let mut stdin = child.stdin.take().unwrap();
writeln!(stdin, "echo");

// sleep a bit so that child can process the input
std::thread::sleep(std::time::Duration::from_millis(500));

// send SIGINT to the child
nix::sys::signal::kill(
nix::unistd::Pid::from_raw(child.id() as i32),
nix::sys::signal::Signal::SIGINT
).expect("cannot send ctrl-c");

// wait for child to terminate
child.wait().unwrap();
}

您应该能够使用此方法发送各种信号。对于更高级的“交互性”(例如查询终端大小的 vi 之类的子程序),您需要创建一个伪终端,就像@hansaplast 在他的解决方案中所做的那样。

关于unix - 通过将 ctrl-c 发送到标准输入来将 SIGINT 发送到进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43788943/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com