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