英文:
Stop command execution and exit process in raw mode
问题
以下是翻译好的部分:
以下代码执行一个命令,然后允许您使用Ctrl + C退出进程:
use std::process::Command;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{stdin, stdout, Write};
fn main() {
let stdin = stdin();
let mut stdout = stdout().into_raw_mode().unwrap();
let mut command = Command::new("script");
command
.arg("-qec")
.arg("sleep 5 && echo test")
.arg("/dev/null");
let output = command.output();
println!("output: {:?}", output);
for c in stdin.keys() {
match c.unwrap() {
Key::Char(c) => println!("{}\r\n", c),
Key::Ctrl('c') => {
println!("Ctrl + C\r\n");
write!(stdout, "{}", termion::cursor::Show).unwrap();
std::process::exit(0);
}
_ => {}
}
stdout.flush().unwrap();
}
}
您必须等待命令执行完成,然后才能按Ctrl + C退出程序。
如何在后台监听Ctrl + C,以便即使在命令运行时也能退出进程(类似于非原始模式中的中断命令)?
英文:
The following code executes a command, then enables you to exit the process with Ctrl + C:
use std::process::Command;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{stdin, stdout, Write};
fn main() {
let stdin = stdin();
let mut stdout = stdout().into_raw_mode().unwrap();
let mut command = Command::new("script");
command
.arg("-qec")
.arg("sleep 5 && echo test")
.arg("/dev/null");
let output = command.output();
println!("output: {:?}", output);
for c in stdin.keys() {
match c.unwrap() {
Key::Char(c) => println!("{}\r\n", c),
Key::Ctrl('c') => {
println!("Ctrl + C\r\n");
write!(stdout, "{}", termion::cursor::Show).unwrap();
std::process::exit(0);
}
_ => {}
}
stdout.flush().unwrap();
}
}
You have to wait for the command to be executed to be able to press Ctrl + C and exit the program.
How to listen to Ctrl + C in the background so that the process can exit even when the command is running (interrupting the command like in non-raw mode)?
答案1
得分: 0
以下是您提供的代码的翻译部分:
我不确定这是否是最佳方法,但它有效。我生成了三个并发线程:一个用于`stdout`,另一个用于`stderr`,第三个用于监听Ctrl + C。
use std::{
io::{BufRead, BufReader},
process::{Command, Stdio},
};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{stdin, stdout, Write};
fn main() {
let stdin = stdin();
std::thread::spawn(move || {
for c in stdin().keys() {
match c.unwrap() {
Key::Ctrl('c') => {
println!("Ctrl + C\r\n");
std::process::exit(0);
}
_ => {}
}
}
});
let mut stdout = stdout().into_raw_mode().unwrap();
stdout.flush().unwrap();
let mut command = Command::new("script");
command
.arg("-qec")
.arg("sleep 5 && echo test")
.arg("/dev/null");
command.stdout(Stdio::piped());
command.stderr(Stdio::piped());
let mut child = command.spawn().expect("failed to spawn command");
let stdout_pipe = child.stdout.take().unwrap();
let stdout_reader = BufReader::new(stdout_pipe);
let stderr_pipe = child.stderr.take().unwrap();
let stderr_reader = BufReader::new(stderr_pipe);
let stdout_thread = std::thread::spawn(move || {
for line in stdout_reader.lines() {
if let Ok(line) = line {
print!("{}\r\n", line);
}
}
});
let stderr_thread = std::thread::spawn(move || {
for line in stderr_reader.lines() {
if let Ok(line) = line {
print!("{}\r\n", line);
}
}
});
let status = child.wait().expect("failed to wait for command");
stdout_thread.join().expect("failed to join stdout thread");
stderr_thread.join().expect("failed to join stderr thread");
println!("status: {}", status);
}
请注意,我只提供了代码的翻译部分,没有包括问题或其他内容。如果您需要任何其他帮助,请随时告诉我。
英文:
I'm not sure if this is the best method, but it works. I spawned three concurrent threads: one for stdout
, another for stderr
, and a third one for listening to Ctrl + C.
use std::{
io::{BufRead, BufReader},
process::{Command, Stdio},
};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{stdin, stdout, Write};
fn main() {
let stdin = stdin();
std::thread::spawn(move || {
for c in stdin().keys() {
match c.unwrap() {
Key::Ctrl('c') => {
println!("Ctrl + C\r\n");
std::process::exit(0);
}
_ => {}
}
}
});
let mut stdout = stdout().into_raw_mode().unwrap();
stdout.flush().unwrap();
let mut command = Command::new("script");
command
.arg("-qec")
.arg("sleep 5 && echo test")
.arg("/dev/null");
command.stdout(Stdio::piped());
command.stderr(Stdio::piped());
let mut child = command.spawn().expect("failed to spawn command");
let stdout_pipe = child.stdout.take().unwrap();
let stdout_reader = BufReader::new(stdout_pipe);
let stderr_pipe = child.stderr.take().unwrap();
let stderr_reader = BufReader::new(stderr_pipe);
let stdout_thread = std::thread::spawn(move || {
for line in stdout_reader.lines() {
if let Ok(line) = line {
print!("{}\r\n", line);
}
}
});
let stderr_thread = std::thread::spawn(move || {
for line in stderr_reader.lines() {
if let Ok(line) = line {
print!("{}\r\n", line);
}
}
});
let status = child.wait().expect("failed to wait for command");
stdout_thread.join().expect("failed to join stdout thread");
stderr_thread.join().expect("failed to join stderr thread");
println!("status: {}", status);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论