Feat: posix compliant pwd.
This commit is contained in:
parent
61f1545ff2
commit
8fe4c42596
99
src/main.rs
99
src/main.rs
|
@ -1,11 +1,7 @@
|
|||
use std::env;
|
||||
use std::io::{stdin, stdout, Write};
|
||||
use std::path::Path;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::{env, fs, io::{stdin, stdout, Write}, path::Path, process::{exit, Child, Command, Stdio}};
|
||||
|
||||
|
||||
fn main(){
|
||||
let mut status=0;
|
||||
fn main() {
|
||||
let mut status = 0;
|
||||
let user = env::var("USER").unwrap();
|
||||
let home_dir = format!("{}{}", "/home/", user);
|
||||
let mut pwd = env::current_dir().unwrap();
|
||||
|
@ -23,7 +19,7 @@ fn main(){
|
|||
let mut commands = input.trim().split(" | ").peekable();
|
||||
let mut previous_command = None;
|
||||
|
||||
while let Some(command) = commands.next() {
|
||||
while let Some(command) = commands.next() {
|
||||
// Other shell variables that can be changed
|
||||
|
||||
// everything after the first whitespace character is interpreted as args to the command
|
||||
|
@ -32,31 +28,32 @@ fn main(){
|
|||
let args = parts;
|
||||
|
||||
match command {
|
||||
"true" | ":" => {
|
||||
| "true" | ":" => {
|
||||
status = 0;
|
||||
},
|
||||
"false" => {
|
||||
| "false" => {
|
||||
status = 1;
|
||||
},
|
||||
"echo" => {
|
||||
let args: Vec<&str> = args/*.peekable().peek().map_or("", |x| *x).split(" ")*/.collect();
|
||||
| "echo" => {
|
||||
let args: Vec<&str> = args // .peekable().peek().map_or("", |x| *x).split(" ")
|
||||
.collect();
|
||||
for arg in args {
|
||||
if arg.contains("$") {
|
||||
match arg {
|
||||
"$?" => {
|
||||
| "$?" => {
|
||||
print!("{}", status);
|
||||
},
|
||||
"$PWD" => {
|
||||
| "$PWD" => {
|
||||
print!("{}", pwd.display());
|
||||
},
|
||||
"$USER" => {
|
||||
| "$USER" => {
|
||||
print!("{}", user);
|
||||
},
|
||||
"$HOME" => {
|
||||
| "$HOME" => {
|
||||
print!("{}", home_dir);
|
||||
},
|
||||
arg => {
|
||||
print!("\n");
|
||||
| arg => {
|
||||
print!("\n");
|
||||
}
|
||||
}
|
||||
print!(" ");
|
||||
|
@ -68,7 +65,7 @@ fn main(){
|
|||
stdout().flush().unwrap();
|
||||
println!();
|
||||
},
|
||||
"cd" => {
|
||||
| "cd" => {
|
||||
let new_dir = args.peekable().peek().map_or(home_dir.clone(), |x| (*x).to_string());
|
||||
let root = Path::new(&new_dir);
|
||||
if let Err(e) = env::set_current_dir(&root) {
|
||||
|
@ -76,17 +73,31 @@ fn main(){
|
|||
}
|
||||
|
||||
previous_command = None;
|
||||
pwd=env::current_dir().unwrap();
|
||||
// current_dir() follows symlinks which isn't always accurate.
|
||||
pwd = root.to_path_buf();
|
||||
},
|
||||
"pwd" => {
|
||||
| "pwd" => {
|
||||
let args: Vec<&str> = args.collect();
|
||||
let mut output = Output::Logical;
|
||||
for i in args {
|
||||
if &i[..] == "-L" {
|
||||
output = Output::Logical;
|
||||
} else if &i[..] == "-P" {
|
||||
output = Output::Physical;
|
||||
}
|
||||
}
|
||||
match output {
|
||||
| Output::Logical => println!("{}", get_logical_dir()),
|
||||
| Output::Physical => {
|
||||
println!("{}", fs::canonicalize(get_logical_dir()).unwrap().to_string_lossy())
|
||||
}
|
||||
}
|
||||
println!("{}", pwd.display());
|
||||
},
|
||||
"exit" => return,
|
||||
"#" => {},
|
||||
command => {
|
||||
let stdin = previous_command
|
||||
.map_or(Stdio::inherit(),
|
||||
|output: Child| Stdio::from(output.stdout.unwrap()));
|
||||
| "exit" => return,
|
||||
| "#" => {},
|
||||
| command => {
|
||||
let stdin = previous_command.map_or(Stdio::inherit(), |output: Child| Stdio::from(output.stdout.unwrap()));
|
||||
|
||||
let stdout = if commands.peek().is_some() {
|
||||
// there is another command piped behind this one
|
||||
|
@ -98,20 +109,18 @@ fn main(){
|
|||
Stdio::inherit()
|
||||
};
|
||||
|
||||
let output = Command::new(command)
|
||||
.args(args)
|
||||
.stdin(stdin)
|
||||
.stdout(stdout)
|
||||
.spawn();
|
||||
let output = Command::new(command).args(args).stdin(stdin).stdout(stdout).spawn();
|
||||
|
||||
match output {
|
||||
Ok(output) => { previous_command = Some(output); },
|
||||
Err(e) => {
|
||||
| Ok(output) => {
|
||||
previous_command = Some(output);
|
||||
},
|
||||
| Err(e) => {
|
||||
previous_command = None;
|
||||
eprintln!("{}", e);
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,6 +128,22 @@ fn main(){
|
|||
// block until the final command has finished
|
||||
final_command.wait().unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn get_logical_dir() -> String {
|
||||
// current_dir follows symlinks which isn't what we want with
|
||||
// logical pwd.
|
||||
match env::var("PWD") {
|
||||
| Ok(d) => d,
|
||||
| Err(e) => {
|
||||
eprintln!("Could not read environment variable $PWD: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Output {
|
||||
Logical,
|
||||
Physical
|
||||
}
|
||||
|
|
36
src/pwd.rs
36
src/pwd.rs
|
@ -1,36 +0,0 @@
|
|||
use std::{env, fs, process::exit};
|
||||
fn main() {
|
||||
let mut args: Vec<String> = env::args().collect();
|
||||
args.remove(0);
|
||||
let mut output = Output::Logical;
|
||||
for i in args {
|
||||
if &i[..] == "-L" {
|
||||
output = Output::Logical;
|
||||
} else if &i[..] == "-P" {
|
||||
output = Output::Physical;
|
||||
}
|
||||
}
|
||||
match output {
|
||||
| Output::Logical => println!("{}", get_logical_dir()),
|
||||
| Output::Physical => {
|
||||
println!("{}", fs::canonicalize(get_logical_dir()).unwrap().to_string_lossy())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_logical_dir() -> String {
|
||||
// current_dir follows symlinks which isn't what we want with
|
||||
// logical pwd.
|
||||
match env::var("PWD") {
|
||||
| Ok(d) => d,
|
||||
| Err(e) => {
|
||||
eprintln!("Could not read environment variable $PWD: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Output {
|
||||
Logical,
|
||||
Physical
|
||||
}
|
Loading…
Reference in New Issue