Stop command execution and exit process in raw mode.

huangapple go评论103阅读模式
英文:

Stop command execution and exit process in raw mode

问题

以下是翻译好的部分:

以下代码执行一个命令,然后允许您使用Ctrl + C退出进程:

  1. use std::process::Command;
  2. use termion::event::Key;
  3. use termion::input::TermRead;
  4. use termion::raw::IntoRawMode;
  5. use std::io::{stdin, stdout, Write};
  6. fn main() {
  7. let stdin = stdin();
  8. let mut stdout = stdout().into_raw_mode().unwrap();
  9. let mut command = Command::new("script");
  10. command
  11. .arg("-qec")
  12. .arg("sleep 5 && echo test")
  13. .arg("/dev/null");
  14. let output = command.output();
  15. println!("output: {:?}", output);
  16. for c in stdin.keys() {
  17. match c.unwrap() {
  18. Key::Char(c) => println!("{}\r\n", c),
  19. Key::Ctrl('c') => {
  20. println!("Ctrl + C\r\n");
  21. write!(stdout, "{}", termion::cursor::Show).unwrap();
  22. std::process::exit(0);
  23. }
  24. _ => {}
  25. }
  26. stdout.flush().unwrap();
  27. }
  28. }

您必须等待命令执行完成,然后才能按Ctrl + C退出程序。

如何在后台监听Ctrl + C,以便即使在命令运行时也能退出进程(类似于非原始模式中的中断命令)?

英文:

The following code executes a command, then enables you to exit the process with Ctrl + C:

  1. use std::process::Command;
  2. use termion::event::Key;
  3. use termion::input::TermRead;
  4. use termion::raw::IntoRawMode;
  5. use std::io::{stdin, stdout, Write};
  6. fn main() {
  7. let stdin = stdin();
  8. let mut stdout = stdout().into_raw_mode().unwrap();
  9. let mut command = Command::new("script");
  10. command
  11. .arg("-qec")
  12. .arg("sleep 5 && echo test")
  13. .arg("/dev/null");
  14. let output = command.output();
  15. println!("output: {:?}", output);
  16. for c in stdin.keys() {
  17. match c.unwrap() {
  18. Key::Char(c) => println!("{}\r\n", c),
  19. Key::Ctrl('c') => {
  20. println!("Ctrl + C\r\n");
  21. write!(stdout, "{}", termion::cursor::Show).unwrap();
  22. std::process::exit(0);
  23. }
  24. _ => {}
  25. }
  26. stdout.flush().unwrap();
  27. }
  28. }

Rust Playground

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

以下是您提供的代码的翻译部分:

  1. 我不确定这是否是最佳方法,但它有效。我生成了三个并发线程:一个用于`stdout`,另一个用于`stderr`,第三个用于监听Ctrl + C
  2. use std::{
  3. io::{BufRead, BufReader},
  4. process::{Command, Stdio},
  5. };
  6. use termion::event::Key;
  7. use termion::input::TermRead;
  8. use termion::raw::IntoRawMode;
  9. use std::io::{stdin, stdout, Write};
  10. fn main() {
  11. let stdin = stdin();
  12. std::thread::spawn(move || {
  13. for c in stdin().keys() {
  14. match c.unwrap() {
  15. Key::Ctrl('c') => {
  16. println!("Ctrl + C\r\n");
  17. std::process::exit(0);
  18. }
  19. _ => {}
  20. }
  21. }
  22. });
  23. let mut stdout = stdout().into_raw_mode().unwrap();
  24. stdout.flush().unwrap();
  25. let mut command = Command::new("script");
  26. command
  27. .arg("-qec")
  28. .arg("sleep 5 && echo test")
  29. .arg("/dev/null");
  30. command.stdout(Stdio::piped());
  31. command.stderr(Stdio::piped());
  32. let mut child = command.spawn().expect("failed to spawn command");
  33. let stdout_pipe = child.stdout.take().unwrap();
  34. let stdout_reader = BufReader::new(stdout_pipe);
  35. let stderr_pipe = child.stderr.take().unwrap();
  36. let stderr_reader = BufReader::new(stderr_pipe);
  37. let stdout_thread = std::thread::spawn(move || {
  38. for line in stdout_reader.lines() {
  39. if let Ok(line) = line {
  40. print!("{}\r\n", line);
  41. }
  42. }
  43. });
  44. let stderr_thread = std::thread::spawn(move || {
  45. for line in stderr_reader.lines() {
  46. if let Ok(line) = line {
  47. print!("{}\r\n", line);
  48. }
  49. }
  50. });
  51. let status = child.wait().expect("failed to wait for command");
  52. stdout_thread.join().expect("failed to join stdout thread");
  53. stderr_thread.join().expect("failed to join stderr thread");
  54. println!("status: {}", status);
  55. }

请注意,我只提供了代码的翻译部分,没有包括问题或其他内容。如果您需要任何其他帮助,请随时告诉我。

英文:

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.

  1. use std::{
  2. io::{BufRead, BufReader},
  3. process::{Command, Stdio},
  4. };
  5. use termion::event::Key;
  6. use termion::input::TermRead;
  7. use termion::raw::IntoRawMode;
  8. use std::io::{stdin, stdout, Write};
  9. fn main() {
  10. let stdin = stdin();
  11. std::thread::spawn(move || {
  12. for c in stdin().keys() {
  13. match c.unwrap() {
  14. Key::Ctrl('c') => {
  15. println!("Ctrl + C\r\n");
  16. std::process::exit(0);
  17. }
  18. _ => {}
  19. }
  20. }
  21. });
  22. let mut stdout = stdout().into_raw_mode().unwrap();
  23. stdout.flush().unwrap();
  24. let mut command = Command::new("script");
  25. command
  26. .arg("-qec")
  27. .arg("sleep 5 && echo test")
  28. .arg("/dev/null");
  29. command.stdout(Stdio::piped());
  30. command.stderr(Stdio::piped());
  31. let mut child = command.spawn().expect("failed to spawn command");
  32. let stdout_pipe = child.stdout.take().unwrap();
  33. let stdout_reader = BufReader::new(stdout_pipe);
  34. let stderr_pipe = child.stderr.take().unwrap();
  35. let stderr_reader = BufReader::new(stderr_pipe);
  36. let stdout_thread = std::thread::spawn(move || {
  37. for line in stdout_reader.lines() {
  38. if let Ok(line) = line {
  39. print!("{}\r\n", line);
  40. }
  41. }
  42. });
  43. let stderr_thread = std::thread::spawn(move || {
  44. for line in stderr_reader.lines() {
  45. if let Ok(line) = line {
  46. print!("{}\r\n", line);
  47. }
  48. }
  49. });
  50. let status = child.wait().expect("failed to wait for command");
  51. stdout_thread.join().expect("failed to join stdout thread");
  52. stderr_thread.join().expect("failed to join stderr thread");
  53. println!("status: {}", status);
  54. }

Note: ctrl doesn't seem to work with Termion's raw mode.

huangapple
  • 本文由 发表于 2023年5月14日 15:39:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76246357.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定