Skip to content

Commit 79345cc

Browse files
zimurghbudziq
authored andcommitted
Add "Run an external command passing it stdin and check for an error code"
1 parent 5d41607 commit 79345cc

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/basics.md

+57-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
| [Generate random numbers with given distribution][ex-rand-dist] | [![rand-badge]][rand] | [![cat-science-badge]][cat-science] |
1010
| [Generate random values of a custom type][ex-rand-custom] | [![rand-badge]][rand] | [![cat-science-badge]][cat-science] |
1111
| [Run an external command and process stdout][ex-parse-subprocess-output] | [![regex-badge]][regex] | [![cat-os-badge]][cat-os] [![cat-text-processing-badge]][cat-text-processing] |
12+
| [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] |
1213
| [Run piped external commands][ex-run-piped-external-commands] | [![std-badge]][std] | [![cat-os-badge]][cat-os] |
1314
| [Filter a log file by matching multiple regular expressions][ex-regex-filter-log] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing]
1415
| [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
@@ -328,14 +329,69 @@ fn run() -> Result<()> {
328329
# quick_main!(run);
329330
```
330331

332+
[ex-parse-subprocess-input]: #ex-parse-subprocess-input
333+
<a name="ex-parse-subprocess-input"></a>
334+
## Run an external command passing it stdin and check for an error code
335+
336+
[![std-badge]][std] [![cat-os-badge]][cat-os]
337+
338+
Opens the `python` interpreter using an external [`Command`] and passes it a python statement
339+
for execution. [`Output`] of said statement is then parsed.
340+
341+
```rust,no_run
342+
# #[macro_use]
343+
# extern crate error_chain;
344+
#
345+
use std::collections::HashSet;
346+
use std::io::Write;
347+
use std::process::{Command, Stdio};
348+
#
349+
# error_chain!{
350+
# errors { CmdError }
351+
# foreign_links {
352+
# Io(std::io::Error);
353+
# Utf8(std::string::FromUtf8Error);
354+
# }
355+
# }
356+
357+
fn run() -> Result<()> {
358+
let mut child = Command::new("python").stdin(Stdio::piped())
359+
.stderr(Stdio::piped())
360+
.stdout(Stdio::piped())
361+
.spawn()?;
362+
363+
child.stdin
364+
.as_mut()
365+
.ok_or("Child process stdin has not been captured!")?
366+
.write_all(b"import this; copyright(); credits(); exit()")?;
367+
368+
let output = child.wait_with_output()?;
369+
370+
if output.status.success() {
371+
let raw_output = String::from_utf8(output.stdout)?;
372+
let words = raw_output.split_whitespace()
373+
.map(|s| s.to_lowercase())
374+
.collect::<HashSet<_>>();
375+
println!("Found {} unique words:", words.len());
376+
println!("{:#?}", words);
377+
Ok(())
378+
} else {
379+
let err = String::from_utf8(output.stderr)?;
380+
bail!("External command failed:\n {}", err)
381+
}
382+
}
383+
#
384+
# quick_main!(run);
385+
```
386+
331387
[ex-run-piped-external-commands]: #ex-run-piped-external-commands
332388
<a name="ex-run-piped-external-commands"></a>
333389
## Run piped external commands
334390

335391
[![std-badge]][std] [![cat-os-badge]][cat-os]
336392

337393
Shows up to the 10<sup>th</sup> biggest files and subdirectories in
338-
the current working directory. It is equivalant to run: `du -ah . |
394+
the current working directory. It is equivalent to run: `du -ah . |
339395
sort -hr | head -n 10`.
340396

341397
It spawns Unix processes which are represented as [`Command`]s. In

src/intro.md

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ community. It needs and welcomes help. For details see
2727
| [Generate random numbers with given distribution][ex-rand-dist] | [![rand-badge]][rand] | [![cat-science-badge]][cat-science] |
2828
| [Generate random values of a custom type][ex-rand-custom] | [![rand-badge]][rand] | [![cat-science-badge]][cat-science] |
2929
| [Run an external command and process stdout][ex-parse-subprocess-output] | [![regex-badge]][regex] | [![cat-os-badge]][cat-os] [![cat-text-processing-badge]][cat-text-processing] |
30+
| [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] |
3031
| [Run piped external commands][ex-run-piped-external-commands] | [![std-badge]][std] | [![cat-os-badge]][cat-os] |
3132
| [Filter a log file by matching multiple regular expressions][ex-regex-filter-log] | [![regex-badge]][regex] | [![cat-text-processing-badge]][cat-text-processing]
3233
| [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
@@ -174,6 +175,7 @@ community. It needs and welcomes help. For details see
174175
[ex-invalid-csv]: encoding.html#ex-invalid-csv
175176
[ex-paginated-api]: net.html#ex-paginated-api
176177
[ex-parse-subprocess-output]: basics.html#ex-parse-subprocess-output
178+
[ex-parse-subprocess-input]: basics.html#ex-parse-subprocess-input
177179
[ex-run-piped-external-commands]: basics.html#ex-run-piped-external-commands
178180
[ex-verify-extract-email]: basics.html#ex-verify-extract-email
179181
[ex-percent-encode]: encoding.html#ex-percent-encode

0 commit comments

Comments
 (0)