@@ -108,277 +108,23 @@ fn decode(mut bytes: &[u8]) -> Result<Payload> {
108
108
109
109
[ ex-parse-subprocess-output ] : #ex-parse-subprocess-output
110
110
<a name =" ex-parse-subprocess-output " ></a >
111
- ## Run an external command and process stdout
112
-
113
- [ ![ regex-badge]] [ regex ] [ ![ cat-os-badge]] [ cat-os ] [ ![ cat-text-processing-badge]] [ cat-text-processing ]
114
-
115
- Runs ` git log --oneline ` as an external [ ` Command ` ] and inspects its [ ` Output ` ]
116
- using [ ` Regex ` ] to get the hash and message of the last 5 commits.
117
-
118
- ``` rust,no_run
119
- # #[macro_use]
120
- # extern crate error_chain;
121
- extern crate regex;
122
-
123
- use std::process::Command;
124
- use regex::Regex;
125
- #
126
- # error_chain!{
127
- # foreign_links {
128
- # Io(std::io::Error);
129
- # Regex(regex::Error);
130
- # Utf8(std::string::FromUtf8Error);
131
- # }
132
- # }
133
-
134
- #[derive(PartialEq, Default, Clone, Debug)]
135
- struct Commit {
136
- hash: String,
137
- message: String,
138
- }
139
-
140
- fn run() -> Result<()> {
141
- let output = Command::new("git").arg("log").arg("--oneline").output()?;
142
-
143
- if !output.status.success() {
144
- bail!("Command executed with failing error code");
145
- }
146
-
147
- let pattern = Regex::new(r"(?x)
148
- ([0-9a-fA-F]+) # commit hash
149
- (.*) # The commit message")?;
150
-
151
- String::from_utf8(output.stdout)?
152
- .lines()
153
- .filter_map(|line| pattern.captures(line))
154
- .map(|cap| {
155
- Commit {
156
- hash: cap[1].to_string(),
157
- message: cap[2].trim().to_string(),
158
- }
159
- })
160
- .take(5)
161
- .for_each(|x| println!("{:?}", x));
162
-
163
- Ok(())
164
- }
165
- #
166
- # quick_main!(run);
167
- ```
111
+ {{#include os/external/process-output.md}}
168
112
169
113
[ ex-parse-subprocess-input ] : #ex-parse-subprocess-input
170
114
<a name =" ex-parse-subprocess-input " ></a >
171
- ## Run an external command passing it stdin and check for an error code
172
-
173
- [ ![ std-badge]] [ std ] [ ![ cat-os-badge]] [ cat-os ]
174
-
175
- Opens the ` python ` interpreter using an external [ ` Command ` ] and passes it a python statement
176
- for execution. [ ` Output ` ] of said statement is then parsed.
177
-
178
- ``` rust,no_run
179
- # #[macro_use]
180
- # extern crate error_chain;
181
- #
182
- use std::collections::HashSet;
183
- use std::io::Write;
184
- use std::process::{Command, Stdio};
185
- #
186
- # error_chain!{
187
- # errors { CmdError }
188
- # foreign_links {
189
- # Io(std::io::Error);
190
- # Utf8(std::string::FromUtf8Error);
191
- # }
192
- # }
193
-
194
- fn run() -> Result<()> {
195
- let mut child = Command::new("python").stdin(Stdio::piped())
196
- .stderr(Stdio::piped())
197
- .stdout(Stdio::piped())
198
- .spawn()?;
199
-
200
- child.stdin
201
- .as_mut()
202
- .ok_or("Child process stdin has not been captured!")?
203
- .write_all(b"import this; copyright(); credits(); exit()")?;
204
-
205
- let output = child.wait_with_output()?;
206
-
207
- if output.status.success() {
208
- let raw_output = String::from_utf8(output.stdout)?;
209
- let words = raw_output.split_whitespace()
210
- .map(|s| s.to_lowercase())
211
- .collect::<HashSet<_>>();
212
- println!("Found {} unique words:", words.len());
213
- println!("{:#?}", words);
214
- Ok(())
215
- } else {
216
- let err = String::from_utf8(output.stderr)?;
217
- bail!("External command failed:\n {}", err)
218
- }
219
- }
220
- #
221
- # quick_main!(run);
222
- ```
115
+ {{#include os/external/send-input.md}}
223
116
224
117
[ ex-run-piped-external-commands ] : #ex-run-piped-external-commands
225
118
<a name =" ex-run-piped-external-commands " ></a >
226
- ## Run piped external commands
227
-
228
- [ ![ std-badge]] [ std ] [ ![ cat-os-badge]] [ cat-os ]
229
-
230
- Shows up to the 10<sup >th</sup > biggest files and subdirectories in
231
- the current working directory. It is equivalent to run: `du -ah . |
232
- sort -hr | head -n 10`.
233
-
234
- It spawns Unix processes which are represented as [ ` Command ` ] s. In
235
- order to capture the output of a child process it is necessary to
236
- create a new [ ` Stdio::piped ` ] between parent and child.
237
-
238
- ``` rust,no_run
239
- # #[macro_use]
240
- # extern crate error_chain;
241
- #
242
- use std::process::{Command, Stdio};
243
- #
244
- # error_chain! {
245
- # foreign_links {
246
- # Io(std::io::Error);
247
- # Utf8(std::string::FromUtf8Error);
248
- # }
249
- # }
250
-
251
- fn run() -> Result<()> {
252
- let directory = std::env::current_dir()?;
253
- let du_output = Command::new("du")
254
- .arg("-ah")
255
- .arg(&directory)
256
- .stdout(Stdio::piped())
257
- .spawn()?
258
- .stdout
259
- .ok_or_else(|| "Could not capture `du` standard output.")?;
260
-
261
- let sort_output = Command::new("sort")
262
- .arg("-hr")
263
- .stdin(du_output)
264
- .stdout(Stdio::piped())
265
- .spawn()?
266
- .stdout
267
- .ok_or_else(|| "Could not capture `sort` standard output.")?;
268
-
269
- let head_output = Command::new("head")
270
- .args(&["-n", "10"])
271
- .stdin(sort_output)
272
- .stdout(Stdio::piped())
273
- .spawn()?
274
- .wait_with_output()?;
275
-
276
- println!(
277
- "Top 10 biggest files and directories in '{}':\n{}",
278
- directory.display(),
279
- String::from_utf8(head_output.stdout)?
280
- );
281
-
282
- Ok(())
283
- }
284
- #
285
- # quick_main!(run);
286
- ```
119
+ {{#include os/external/piped.md}}
287
120
288
121
[ ex-redirect-stdout-stderr-same-file ] : #ex-redirect-stdout-stderr-same-file
289
122
<a name =" ex-redirect-stdout-stderr-same-file " ></a >
290
- ## Redirect both stdout and stderr of child process to the same file
291
-
292
- [ ![ std-badge]] [ std ] [ ![ cat-os-badge]] [ cat-os ]
293
-
294
- Spawns a child process and redirects ` stdout ` and ` stderr ` to the same
295
- file. It follows the same idea as [ run piped external
296
- commands] ( #ex-run-piped-external-commands ) , however [ ` process::Stdio ` ]
297
- will write to the provided files and beforehand, [ ` File::try_clone ` ]
298
- is used to reference the same file handle for ` stdout ` and
299
- ` stderr ` . It will ensure that both handles write with the same cursor
300
- position.
301
-
302
- The below recipe is equivalent to run the Unix shell command `ls
303
- . oops >out.txt 2>&1`.
304
-
305
- ``` rust,no_run
306
- # #[macro_use]
307
- # extern crate error_chain;
308
- #
309
- use std::fs::File;
310
- use std::process::{Command, Stdio};
311
-
312
- # error_chain! {
313
- # foreign_links {
314
- # Io(std::io::Error);
315
- # }
316
- # }
317
- #
318
- fn run() -> Result<()> {
319
- let outputs = File::create("out.txt")?;
320
- let errors = outputs.try_clone()?;
321
-
322
- Command::new("ls")
323
- .args(&[".", "oops"])
324
- .stdout(Stdio::from(outputs))
325
- .stderr(Stdio::from(errors))
326
- .spawn()?
327
- .wait_with_output()?;
328
-
329
- Ok(())
330
- }
331
- #
332
- # quick_main!(run);
333
- ```
123
+ {{#include os/external/error-file.md}}
334
124
335
125
[ ex-continuous-process-output ] : #ex-continuous-process-output
336
126
<a name =" ex-continuous-process-output " ></a >
337
- ## Continuously process child process' outputs
338
-
339
- [ ![ std-badge]] [ std ] [ ![ cat-os-badge]] [ cat-os ]
340
-
341
- In [ Run an external command and process stdout] ( #ex-parse-subprocess-output ) ,
342
- processing doesn't start until external [ ` Command ` ] is finished.
343
- The recipe below creates a new pipe by calling [ ` Stdio::piped ` ] and reads
344
- ` stdout ` continuously as soon as the [ ` BufReader ` ] is updated.
345
-
346
- The below recipe is equivalent to the Unix shell command
347
- ` journalctl | grep usb ` .
348
-
349
- ``` rust,no_run
350
- # #[macro_use]
351
- # extern crate error_chain;
352
- #
353
- use std::process::{Command, Stdio};
354
- use std::io::{BufRead, BufReader};
355
-
356
- # error_chain! {
357
- # foreign_links {
358
- # Io(std::io::Error);
359
- # }
360
- # }
361
- #
362
- fn run() -> Result<()> {
363
- let stdout = Command::new("journalctl")
364
- .stdout(Stdio::piped())
365
- .spawn()?
366
- .stdout
367
- .ok_or_else(|| "Could not capture standard output.")?;
368
-
369
- let reader = BufReader::new(stdout);
370
-
371
- reader
372
- .lines()
373
- .filter_map(|line| line.ok())
374
- .filter(|line| line.find("usb").is_some())
375
- .for_each(|line| println!("{}", line));
376
-
377
- Ok(())
378
- }
379
- #
380
- # quick_main!(run);
381
- ```
127
+ {{#include os/external/continuous.md}}
382
128
383
129
[ ex-regex-filter-log ] : #ex-regex-filter-log
384
130
<a name =" ex-regex-filter-log " ></a >
@@ -657,19 +403,7 @@ fn run() -> Result<()> {
657
403
658
404
[ ex-check-cpu-cores ] : #ex-check-cpu-cores
659
405
<a name =" ex-check-cpu-cores " ></a >
660
- ## Check number of logical cpu cores
661
-
662
- [ ![ num_cpus-badge]] [ num_cpus ] [ ![ cat-hardware-support-badge]] [ cat-hardware-support ]
663
-
664
- Shows the number of logical cpu cores in current machine using [ ` num_cpus::get ` ] .
665
-
666
- ``` rust
667
- extern crate num_cpus;
668
-
669
- fn main () {
670
- println! (" Number of logical cores is {}" , num_cpus :: get ());
671
- }
672
- ```
406
+ {{#include hardware/processor/cpu-count.md}}
673
407
674
408
[ ex-error-chain-simple-error-handling ] : #ex-error-chain-simple-error-handling
675
409
<a name =" ex-error-chain-simple-error-handling " ></a >
0 commit comments