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) == Some('$') => 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 mut parts = line.trim().split_whitespace(); let command = parts.next().unwrap(); match command { "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 tmp = substitute_vars(p); let cd = Path::new(&tmp); env::set_current_dir(&cd)?; } }; }, command => { let child = Command::new(command) .args(parts.map(substitute_vars)) .spawn(); match child { Ok(mut child) => { child.wait()?; }, Err(e) => eprintln!("{}", e) } } } } }