System Command
Objectives: Call system command ls
. If return code is other than 0
, signal error that includes message obtained from stderr. Otherwise read stdout, split lines and present as a list.
Python
import subprocess
target_dir = "/"
status = subprocess.run(["ls", target_dir],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if status.returncode:
msg = status.stderr.decode()
raise Exception(msg)
else:
list_files = status.stdout.decode().split()
print(list_files)
Note: in practice, packages like plumbum
can be a good alternative.
Rust
use std::process::Command; fn main() { let cmd = Command::new("ls") .arg("/") .stdout(std::process::Stdio::piped()) .output() .expect("Failed to invoke command"); if cmd.status.code() == Some(0) { // cmd.status.success() also available let stdout = String::from_utf8(cmd.stdout).unwrap(); let list_files: Vec<&str> = stdout.split("\n").collect(); println!("{:?}", list_files); } else { let stderr = String::from_utf8(cmd.stderr).unwrap(); println!("Error: {}", stderr.trim()); } }
Note: unwrap
has been used for simplicity. In practice this can be replaced by error propagation.
Crystal
cmd = Process.new("ls", args: ["/"],
output: Process::Redirect::Pipe,
error: Process::Redirect::Pipe)
stdout = cmd.output.gets_to_end
stderr = cmd.error.gets_to_end
status = cmd.wait
if status.exit_status == 0
puts stdout.split
else
raise stderr
end
Alternative variant below forwards stderr of the subprocess to stderr of the main process. Doesn't meet objectives but is still worth of mentioning.
stdout = `ls /`
if $?.success? # return code != 0 ?
puts stdout.split
end