pub struct Child {
pub stdin: Option<ChildStdin>,
pub stdout: Option<ChildStdout>,
pub stderr: Option<ChildStderr>,
/* private fields */
}Expand description
A spawned child process.
The process can be in running or exited state. Use status() or
output() to wait for it to exit.
If the Child is dropped, the process keeps running in the background.
§Examples
Spawn a process and wait for it to complete:
use async_process::Command;
Command::new("cp").arg("a.txt").arg("b.txt").status().await?;Fields§
§stdin: Option<ChildStdin>The handle for writing to the child’s standard input (stdin), if it has been captured.
stdout: Option<ChildStdout>The handle for reading from the child’s standard output (stdout), if it has been captured.
stderr: Option<ChildStderr>The handle for reading from the child’s standard error (stderr), if it has been captured.
Implementations§
Source§impl Child
impl Child
Sourcepub fn id(&self) -> u32
pub fn id(&self) -> u32
Returns the OS-assigned process identifier associated with this child.
§Examples
use async_process::Command;
let mut child = Command::new("ls").spawn()?;
println!("id: {}", child.id());Sourcepub fn kill(&mut self) -> Result<()>
pub fn kill(&mut self) -> Result<()>
Forces the child process to exit.
If the child has already exited, an InvalidInput error is returned.
This is equivalent to sending a SIGKILL on Unix platforms.
§Examples
use async_process::Command;
let mut child = Command::new("yes").spawn()?;
child.kill()?;
println!("exit status: {}", child.status().await?);Sourcepub fn try_status(&mut self) -> Result<Option<ExitStatus>>
pub fn try_status(&mut self) -> Result<Option<ExitStatus>>
Returns the exit status if the process has exited.
Unlike status(), this method will not drop the stdin handle.
§Examples
use async_process::Command;
let mut child = Command::new("ls").spawn()?;
match child.try_status()? {
None => println!("still running"),
Some(status) => println!("exited with: {}", status),
}Sourcepub fn status(&mut self) -> impl Future<Output = Result<ExitStatus>>
pub fn status(&mut self) -> impl Future<Output = Result<ExitStatus>>
Drops the stdin handle and waits for the process to exit.
Closing the stdin of the process helps avoid deadlocks. It ensures that the process does not block waiting for input from the parent process while the parent waits for the child to exit.
§Examples
use async_process::{Command, Stdio};
let mut child = Command::new("cp")
.arg("a.txt")
.arg("b.txt")
.spawn()?;
println!("exit status: {}", child.status().await?);Examples found in repository?
8fn main() -> io::Result<()> {
9 async_io::block_on(async {
10 // Spawn a a command of your choice.
11 let mut child = Command::new("sleep")
12 .arg("3")
13 .stdout(Stdio::piped())
14 .stderr(Stdio::piped())
15 .spawn()?;
16
17 // Run a future to drain the stdout of the child.
18 // We can't use output() here because it would be cancelled along with the child when the timeout
19 // expires.
20 let mut stdout = String::new();
21 let drain_stdout = {
22 let buffer = &mut stdout;
23 let mut stdout = child.stdout.take().unwrap();
24
25 async move {
26 stdout.read_to_string(buffer).await?;
27
28 // Wait for the child to exit or the timeout.
29 future::pending().await
30 }
31 };
32
33 // Run a future to drain the stderr of the child.
34 let mut stderr = String::new();
35 let drain_stderr = {
36 let buffer = &mut stderr;
37 let mut stderr = child.stderr.take().unwrap();
38
39 async move {
40 stderr.read_to_string(buffer).await?;
41
42 // Wait for the child to exit or the timeout.
43 future::pending().await
44 }
45 };
46
47 // Run a future that waits for the child to exit.
48 let wait = async move {
49 child.status().await?;
50
51 // Child exited.
52 io::Result::Ok(false)
53 };
54
55 // Run a future that times out after 1 second.
56 let timeout_s = 1;
57 let timeout = async move {
58 Timer::after(std::time::Duration::from_secs(timeout_s)).await;
59
60 // Timed out.
61 Ok(true)
62 };
63
64 // Run the futures concurrently.
65 // Note: For larger scale programs than this you should probably spawn each individual future on
66 // a separate task in an executor.
67 let timed_out = drain_stdout.or(drain_stderr).or(wait).or(timeout).await?;
68
69 if timed_out {
70 println!("The child timed out.");
71 } else {
72 println!("The child exited.");
73 }
74
75 println!("Stdout:\n{stdout}");
76 println!("Stderr:\n{stderr}");
77
78 Ok(())
79 })
80}Sourcepub fn output(self) -> impl Future<Output = Result<Output>>
pub fn output(self) -> impl Future<Output = Result<Output>>
Drops the stdin handle and collects the output of the process.
Closing the stdin of the process helps avoid deadlocks. It ensures that the process does not block waiting for input from the parent process while the parent waits for the child to exit.
In order to capture the output of the process, Command::stdout() and
Command::stderr() must be configured with Stdio::piped().
§Examples
use async_process::{Command, Stdio};
let child = Command::new("ls")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let out = child.output().await?;