mirror of
https://github.com/Bemly/Besh.git
synced 2024-11-22 17:25:06 +00:00
no more.
This commit is contained in:
parent
beab96cf1e
commit
65579f0ae3
@ -1,4 +1,4 @@
|
||||
|
||||
pub fn main(args: Vec<String>) {
|
||||
pub fn main(_args: Vec<String>) {
|
||||
|
||||
}
|
@ -35,68 +35,88 @@
|
||||
// libc::execvp(self.get_program_cstr().as_ptr(), self.get_argv().as_ptr());
|
||||
// source: https://stdrs.dev/nightly/x86_64-unknown-linux-gnu/src/std/sys/unix/process/process_unix.rs.html#473
|
||||
|
||||
|
||||
|
||||
use std::io::{stdin, stdout, Write};
|
||||
use std::process::{Command, exit};
|
||||
|
||||
use std::io::{self, stdin, stdout, Write};
|
||||
use std::process::{Command, exit, Output};
|
||||
use super::error::*;
|
||||
|
||||
// rust 有各种平台实现,可以跨平台编译使用
|
||||
pub fn main(cmd: Vec<String>) {
|
||||
pub fn main(args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
println!("Welcome to the Bemly shell!\n");
|
||||
|
||||
// 快速执行命令
|
||||
if cmd.len() != 0 {
|
||||
// println!("{}", cmd.get(0).unwrap());
|
||||
//
|
||||
if args.len() != 0 {
|
||||
|
||||
// match cmd.get(0).unwrap().to_lowercase().trim() {
|
||||
// // 指定参数功能输出
|
||||
// "-h" | "--help" => println!("toggle use libc shell: -u | --use-libc"),
|
||||
// _ => todo!()
|
||||
// }
|
||||
|
||||
let s = String::from_utf8(
|
||||
Command::new(cmd.get(0).unwrap())
|
||||
.args(cmd.iter().skip(1))
|
||||
.output()
|
||||
.expect("[TODO!] Failed to execute command. 命令执行失败")
|
||||
.stdout
|
||||
).unwrap();
|
||||
println!("{s}");
|
||||
// exec_cmd:命令执行体,命令名
|
||||
// 命令执行体:命令名,参数数组
|
||||
let cmd = args.get(0).unwrap().as_str();
|
||||
exec_cmd(Command::new(cmd).args(args.iter().skip(1)).output(), cmd)?;
|
||||
}
|
||||
|
||||
// 获取用户名和主机名
|
||||
let username = std::env::var("USER")
|
||||
.unwrap_or(String::from_utf8(Command::new("/usr/bin/whoami").output()?.stdout)?);
|
||||
let hostname = std::fs::read_to_string("/etc/hostname")
|
||||
.unwrap_or(String::from("unknown")).replace("\n", "");
|
||||
|
||||
// 获取当前工作目录(先转&str再转String加上所有权)
|
||||
let mut pwd = std::env::current_dir()?.to_str().expect(NOT_FIND_CRR_DIR)
|
||||
.replace(std::env::var("HOME").unwrap_or(String::from("~")).as_str(), "~");
|
||||
|
||||
// 进入循环执行模式
|
||||
loop {
|
||||
|
||||
print!("> ");
|
||||
stdout().flush().expect("[TODO!] Failed to flush stdout. 输出流刷新失败");
|
||||
|
||||
|
||||
print!("{username}@{hostname} {pwd}> ");
|
||||
stdout().flush()?;
|
||||
// 读取用户输入
|
||||
let mut command_buffer = String::new();
|
||||
stdin().read_line(&mut command_buffer).expect("[TODO!] Failed to read line. 读取输入失败");
|
||||
stdin().read_line(&mut command_buffer)?;
|
||||
|
||||
// 捕获指定命令
|
||||
match command_buffer.trim() {
|
||||
"exit" => exit(0),
|
||||
"cd" => todo!(),
|
||||
// 退出程序 没有正则的痛苦 哇的一声就哭出来了昂
|
||||
"exit" | "exit()" | "quit" | "qui" | "qu" | "q" | ":q" => exit(0),
|
||||
// 就是空行
|
||||
"" => println!(),
|
||||
// 执行路径下软件或者脚本
|
||||
s => {
|
||||
// TODO: 屎山代码 分割空格为 实现了迭代器方法的spw对象
|
||||
let mut program = s.split_whitespace();
|
||||
let s = String::from_utf8(
|
||||
Command::new(program.next().unwrap())
|
||||
.args(program)
|
||||
.output()
|
||||
.expect("[TODO!] Failed to execute command. 命令执行失败")
|
||||
.stdout
|
||||
).expect("[TODO!] Failed to convert output to string. 输出转换为字符串失败");
|
||||
println!("{s}");
|
||||
let cmd = program.next().expect(NOT_GET_PROGRAM_NAME);
|
||||
match cmd {
|
||||
"cd" => {
|
||||
// 获取当前工作目录
|
||||
let pwd = std::env::current_dir()?;
|
||||
// 获取用户输入的路径
|
||||
let path = program.next().expect(NOT_GET_PATH);
|
||||
// 获取用户输入的路径
|
||||
let path = std::path::Path::new(path);
|
||||
// 获取用户输入的路径的绝对路径
|
||||
let path = path.canonicalize()?;
|
||||
// 获取用户输入的路径的绝对路径的字符串
|
||||
let path = path.to_str().expect(NOT_GET_PATH);
|
||||
},
|
||||
_ => exec_cmd(Command::new(cmd).args(program).output(), cmd)?
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
fn exec_cmd(result: Result<Output, io::Error>, cmd: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match result {
|
||||
// 匹配Result()结果,成功则从stdout流打印输出结果,失败打印stderr流
|
||||
Ok(output) => { println!("{}", String::from_utf8(output.stdout)?) },
|
||||
Err(e) => { eprintln!("besh: {cmd}: {e}") }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// 参考
|
||||
// source: https://github.com/xitu/gold-miner/blob/master/TODO1/tutorial-write-a-shell-in-c.md
|
5
src/error.rs
Normal file
5
src/error.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub const _FAIL_REFRESH: &str = "a failed refresh 输出流刷新失败";
|
||||
pub const _FAIL_READ_LINE : &str = "failed to read line. 读取输入失败";
|
||||
pub const NOT_GET_PROGRAM_NAME : &str = "failed to get program name. 获取程序名失败";
|
||||
pub const _FAIL_STR_TRANFORM: &str = "Failed to convert output to string. 输出转换为字符串失败";
|
||||
pub const NOT_FIND_CRR_DIR: &str = "failed to find current directory. 获取当前目录失败";
|
@ -2,6 +2,7 @@ use std::env;
|
||||
|
||||
mod common_shell;
|
||||
mod better_truth_tty;
|
||||
mod error;
|
||||
|
||||
use common_shell::main as common_shell;
|
||||
use better_truth_tty::main as unix_shell;
|
||||
@ -11,13 +12,13 @@ fn main() {
|
||||
|
||||
// 没有参数的情况
|
||||
match args.len() {
|
||||
0 => common_shell(args),
|
||||
0 => common_shell(args).unwrap(),
|
||||
_ => match args.get(0).unwrap().to_lowercase().trim() {
|
||||
// 指定参数功能输出
|
||||
"-h" | "--help" => println!("toggle use libc shell: -u | --use-libc"),
|
||||
"-v" | "--version" => println!("BESH version 0.1 \n\t By Bemly_. 2024.08.08"),
|
||||
"-u" | "--use-libc" => unix_shell(args),
|
||||
_ => common_shell(args)
|
||||
_ => common_shell(args).unwrap()
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ fn test_exec() {
|
||||
# [test]
|
||||
fn test_lines() {
|
||||
use std::io::BufRead;
|
||||
|
||||
|
||||
// Ctrl+D 结束 EOF
|
||||
let stdin = io::stdin();
|
||||
let iterator = stdin.lock().lines();
|
||||
@ -89,4 +89,12 @@ fn test_line2() {
|
||||
}
|
||||
|
||||
println!("Exited the loop.");
|
||||
}
|
||||
|
||||
# [test]
|
||||
fn test_get_program() {
|
||||
use std::process::Command;
|
||||
|
||||
let cmd = Command::new("echo");
|
||||
assert_eq!(cmd.get_program(), "echo");
|
||||
}
|
Loading…
Reference in New Issue
Block a user