External Command
Run an external command and process stdout
Runs git log --oneline
as an external Command
and inspects its Output
using Regex
to get the hash and message of the last 5 commits.
Run an external command passing it stdin and check for an error code
Opens the python
interpreter using an external Command
and passes it a
python statement for execution. Output
of statement is then parsed.
Run piped external commands
Shows up to the 10th biggest files and subdirectories in
the current working directory. It is equivalent to running: du -ah . | sort -hr | head -n 10
.
Command
s represent a process. Output of a child process is captured with a
Stdio::piped
between parent and child.
Redirect both stdout and stderr of child process to the same file
Spawns a child process and redirects stdout
and stderr
to the same
file. It follows the same idea as run piped external
commands, however process::Stdio
writes to a specified file. File::try_clone
references the same file handle
for stdout
and stderr
. It will ensure that both handles write with the same
cursor position.
The below recipe is equivalent to run the Unix shell command ls . oops >out.txt 2>&1
.
use std::fs::File;
use std::io::Error;
use std::process::{Command, Stdio};
fn main() -> Result<(), Error> {
let outputs = File::create("out.txt")?;
let errors = outputs.try_clone()?;
Command::new("ls")
.args(&[".", "oops"])
.stdout(Stdio::from(outputs))
.stderr(Stdio::from(errors))
.spawn()?
.wait_with_output()?;
Ok(())
}
Continuously process child process' outputs
In Run an external command and process stdout,
processing doesn't start until external Command
is finished.
The recipe below calls Stdio::piped
to create a pipe, and reads
stdout
continuously as soon as the BufReader
is updated.
The below recipe is equivalent to the Unix shell command
journalctl | grep usb
.
use std::process::{Command, Stdio};
use std::io::{BufRead, BufReader, Error, ErrorKind};
fn main() -> Result<(), Error> {
let stdout = Command::new("journalctl")
.stdout(Stdio::piped())
.spawn()?
.stdout
.ok_or_else(|| Error::new(ErrorKind::Other,"Could not capture standard output."))?;
let reader = BufReader::new(stdout);
reader
.lines()
.filter_map(|line| line.ok())
.filter(|line| line.find("usb").is_some())
.for_each(|line| println!("{}", line));
Ok(())
}
Read Environment Variable
Reads an environment variable via std::env::var.
use std::env;
use std::fs;
use std::io::Error;
fn main() -> Result<(), Error> {
// read `config_path` from the environment variable `CONFIG`.
// If `CONFIG` isn't set, fall back to a default config path.
let config_path = env::var("CONFIG")
.unwrap_or("/etc/myapp/config".to_string());
let config: String = fs::read_to_string(config_path)?;
println!("Config: {}", config);
Ok(())
}