diff --git a/src/basics.md b/src/basics.md index 6e0b5871..83f9ce84 100644 --- a/src/basics.md +++ b/src/basics.md @@ -12,6 +12,7 @@ | [Run an external command passing it stdin and check for an error code][ex-parse-subprocess-input] | [![regex-badge]][regex] | [![cat-os-badge]][cat-os] [![cat-text-processing-badge]][cat-text-processing] | | [Run piped external commands][ex-run-piped-external-commands] | [![std-badge]][std] | [![cat-os-badge]][cat-os] | | [Redirect both stdout and stderr of child process to the same file][ex-redirect-stdout-stderr-same-file] | [![std-badge]][std] | [![cat-os-badge]][cat-os] | +| [Continuously process child process' outputs][ex-continuous-process-output] | [![std-badge]][std] | [![cat-os-badge]][cat-os][![cat-text-processing-badge]][cat-text-processing] | | [Filter a log file by matching multiple regular expressions][ex-regex-filter-log] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing] | [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] | | [Maintain global mutable state][ex-global-mut-state] | [![lazy_static-badge]][lazy_static] | [![cat-rust-patterns-badge]][cat-rust-patterns] | @@ -502,6 +503,55 @@ fn run() -> Result<()> { # quick_main!(run); ``` +[ex-continuous-process-output]: #ex-continuous-process-output + +## Continuously process child process' outputs + +[![std-badge]][std] [![cat-os-badge]][cat-os] + +Contrary to [Run an external command and process +stdout](#ex-parse-subprocess-output), while an external [`Command`] is +running, process its standard output without waiting it to finish. A +new pipe is created by [`Stdio::piped`] and it is read continuously by +a [`BufReader`]. + +The below recipe is equivalent to run the Unix shell command +`journalctl | grep usb`. + +```rust,no_run +# #[macro_use] +# extern crate error_chain; +# +use std::process::{Command, Stdio}; +use std::io::{BufRead, BufReader}; + +# error_chain! { +# foreign_links { +# Io(std::io::Error); +# } +# } +# +fn run() -> Result<()> { + let stdout = Command::new("journalctl") + .stdout(Stdio::piped()) + .spawn()? + .stdout + .ok_or_else(|| "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(()) +} +# +# quick_main!(run); +``` + [ex-regex-filter-log]: #ex-regex-filter-log ## Filter a log file by matching multiple regular expressions diff --git a/src/intro.md b/src/intro.md index 117c3c8f..f8fd9d93 100644 --- a/src/intro.md +++ b/src/intro.md @@ -30,6 +30,7 @@ community. It needs and welcomes help. For details see | [Run an external command passing it stdin and check for an error code][ex-parse-subprocess-input] | [![std-badge]][std] | [![cat-os-badge]][cat-os] | | [Run piped external commands][ex-run-piped-external-commands] | [![std-badge]][std] | [![cat-os-badge]][cat-os] | | [Redirect both stdout and stderr of child process to the same file][ex-redirect-stdout-stderr-same-file] | [![std-badge]][std] | [![cat-os-badge]][cat-os] | +| [Continuously process child process' outputs][ex-continuous-process-output] | [![std-badge]][std] | [![cat-os-badge]][cat-os][![cat-text-processing-badge]][cat-text-processing] | | [Filter a log file by matching multiple regular expressions][ex-regex-filter-log] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing] | [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] | | [Maintain global mutable state][ex-global-mut-state] | [![lazy_static-badge]][lazy_static] | [![cat-rust-patterns-badge]][cat-rust-patterns] | @@ -164,6 +165,7 @@ community. It needs and welcomes help. For details see [ex-check-broken-links]: net.html#ex-check-broken-links [ex-check-cpu-cores]: basics.html#ex-check-cpu-cores [ex-clap-basic]: app.html#ex-clap-basic +[ex-continuous-process-output]: basics.html#ex-continuous-process-output [ex-convert-datetime-timestamp]: basics.html#ex-convert-datetime-timestamp [ex-convert-datetime-timezone]: basics.html#ex-convert-datetime-timezone [ex-crossbeam-spawn]: concurrency.html#ex-crossbeam-spawn diff --git a/src/links.md b/src/links.md index 82d84ebe..fc77ef82 100644 --- a/src/links.md +++ b/src/links.md @@ -110,7 +110,7 @@ Keep lines sorted. [serde-json-badge]: https://badge-cache.kominick.com/crates/v/serde_json.svg?label=serde_json [serde-json]: https://docs.serde.rs/serde_json/ [serde]: https://docs.rs/serde/ -[std-badge]: https://badge-cache.kominick.com/badge/std-1.19.0-blue.svg +[std-badge]: https://badge-cache.kominick.com/badge/std-1.22.1-blue.svg [std]: https://doc.rust-lang.org/std [syslog-badge]: https://badge-cache.kominick.com/crates/v/syslog.svg?label=syslog [syslog]: https://docs.rs/syslog/