英文:
Custom command not echoing anything in the terminal
问题
以下是代码的翻译部分,不包括问题的回答:
以下代码允许您在终端中定义自定义命令。每个自定义命令都有一个`key`(触发命令)、一个`description`和一个`shell_command`(实际命令)。
use std::io::{stdin, stdout, Write};
use std::process::Command;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
struct CustomCommand {
key: char,
description: &'static str,
shell_command: &'static str,
}
impl CustomCommand {
fn execute_shell_command(&self) {
let output = Command::new("sh")
.arg("-c")
.arg(self.shell_command)
.output();
match output {
Ok(output) => {
if output.status.success() {
println!("命令执行成功\r\n");
} else {
println!("命令执行失败\r\n");
}
}
Err(e) => {
println!("执行命令时出错: {:?}\r\n", e);
}
}
}
}
fn main() {
// 打开终端的原始模式
let mut stdout = stdout().into_raw_mode().unwrap();
// 定义可用的命令
let commands = vec![CustomCommand {
key: 'c',
description: "这是一个自定义命令",
shell_command: "echo '自定义命令已执行'",
}];
// 在终端上打印消息
write!(stdout, "请选择一个命令:\r\n").unwrap();
// 列出用户定义的命令
for command in &commands {
write!(stdout, "{} {}\r\n", command.key, command.description).unwrap();
}
stdout.flush().unwrap();
// 从标准输入读取输入
let input = stdin().keys();
// 循环遍历每个按键
for key in input {
// 将按键与可用命令进行匹配
match key.unwrap() {
// 如果按键与命令匹配,则执行它并退出循环
Key::Char(k) if commands.iter().any(|c| c.key == k) => {
let command = commands.iter().find(|c| c.key == k).unwrap();
command.execute_shell_command();
break;
}
// 输出其他字符
Key::Char(c) => {
write!(stdout, "您按下了: {}\r\n", c).unwrap();
stdout.flush().unwrap();
}
// 如果按键是其他任何内容,请忽略
_ => {}
}
}
}
请注意,代码中的问题部分没有翻译。如果您有关于代码的问题,可以随时提出,我将尽力提供帮助。
英文:
The following code lets you define custom commands in the terminal. Each custom command has a key
(which triggers the command), a description
, and a shell_command
(the actual command).
use std::io::{stdin, stdout, Write};
use std::process::Command;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
struct CustomCommand {
key: char,
description: &'static str,
shell_command: &'static str,
}
impl CustomCommand {
fn execute_shell_command(&self) {
let output = Command::new("sh")
.arg("-c")
.arg(self.shell_command)
.output();
match output {
Ok(output) => {
if output.status.success() {
println!("Command executed successfully\r\n");
} else {
println!("Command execution failed\r\n");
}
}
Err(e) => {
println!("Error executing command: {:?}\r\n", e);
}
}
}
}
fn main() {
// Turn on raw mode for the terminal
let mut stdout = stdout().into_raw_mode().unwrap();
// Define the available commands
let commands = vec![CustomCommand {
key: 'c',
description: "This is a custom command",
shell_command: "echo 'Custom command executed'",
}];
// Print the messages to the terminal
write!(stdout, "Please select a command:\r\n").unwrap();
// List the custom commands for the user
for command in &commands {
write!(stdout, "{} {}\r\n", command.key, command.description).unwrap();
}
stdout.flush().unwrap();
// Read input from stdin
let input = stdin().keys();
// Loop over each key that is pressed
for key in input {
// Match the key against the available commands
match key.unwrap() {
// If the key matches a command, execute it and break the loop
Key::Char(k) if commands.iter().any(|c| c.key == k) => {
let command = commands.iter().find(|c| c.key == k).unwrap();
command.execute_shell_command();
break;
}
// Output other characters
Key::Char(c) => {
write!(stdout, "You pressed: {}\r\n", c).unwrap();
stdout.flush().unwrap();
}
// If the key is anything else, ignore it
_ => {}
}
}
}
The command is being executed successfully, but is not echoing anything in the terminal:
Please select a command:
c This is a custom command
Command executed successfully
alex@alex-M52AD-M12AD-A-F-K31AD:~/rust/cc$
Why is this, and how to fix it?
答案1
得分: 2
On success, output
contains a Vec<u8>
in its stdout
member.
You can eventually convert it to a string and display it as some text.
if output.status.success() {
println!("Command executed successfully\r\n");
println!("bytes: {:?}", output.stdout);
let text = String::from_utf8_lossy(&output.stdout);
println!("text: {:?}", text);
}
If you are not interested in capturing the outputs of the command, you can simply use spawn()
; then the outputs of the command will naturally appear in the terminal.
Thanks to @JonasFassbender remark, .status()
is even easier (it waits for the process to terminate, we don't have to).
Here is your code slightly modified.
fn execute_shell_command(&self) {
let status = Command::new("sh")
.arg("-c")
.arg(self.shell_command)
.status();
match status {
Ok(status) => {
if status.success() {
println!("Command executed successfully\r\n");
} else {
println!("Command execution failed\r\n");
}
}
Err(e) => {
println!("Error executing command: {:?}\r\n", e);
}
}
}
英文:
On success, output
contains a Vec<u8>
in its stdout
member.
You can eventually convert it to a string and display it as some text.
if output.status.success() {
println!("Command executed successfully\r\n");
println!("bytes: {:?}", output.stdout);
let text = String::from_utf8_lossy(&output.stdout);
println!("text: {:?}", text);
}
If you are not interested in capturing the outputs of the command, you can simply use spawn()
; then the outputs of the command will naturally appear in the terminal.
Thanks to @JonasFassbender remark, .status()
is even easier (it waits for the process to terminate, we don't have to).
Here is your code slightly modified.
fn execute_shell_command(&self) {
let status = Command::new("sh")
.arg("-c")
.arg(self.shell_command)
.status();
match status {
Ok(status) => {
if status.success() {
println!("Command executed successfully\r\n");
} else {
println!("Command execution failed\r\n");
}
}
Err(e) => {
println!("Error executing command: {:?}\r\n", e);
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论