use std::io::{self,stdin,stdout,Write}; use std::str::FromStr; use std::process::{Command}; use std::env; use std::path::Path; fn substitute_vars(word: &str) -> String { match word { "~" => env::var("HOME").unwrap(), w if w.chars().nth(0).unwrap() == '~' => w.replace("~", env::var("HOME").unwrap().as_str()), w if w.chars().nth(0).unwrap() == '$' => String::from_str(w).unwrap(), w => String::from_str(w).unwrap() } } fn main() -> io::Result<()> { loop { stdout().write_all(b"> ")?; stdout().flush()?; let mut line = String::new(); stdin().read_line(&mut line).unwrap(); let tmp = line.trim().split_whitespace() .collect::>(); let mut parts = tmp.iter() .map(|x| substitute_vars(*x)); let command = parts.next().unwrap(); match command.as_str() { "exit" => return Ok(()), "cd" => { // change directory match parts.next() { None => { let home = env::var("HOME").unwrap(); let cd = Path::new(home.as_str()); env::set_current_dir(&cd)?; }, Some(p) => { let cd = Path::new(&p); env::set_current_dir(&cd)?; } }; }, command => { let child = Command::new(command) .args(parts) .spawn(); match child { Ok(mut child) => { child.wait()?; }, Err(e) => eprintln!("{}", e) } } } } }