Skip to main content

Command

Struct Command 

Source
pub struct Command { /* private fields */ }
Expand description

A builder for spawning processes.

§Examples

use async_process::Command;

let output = Command::new("sh").arg("-c").arg("echo hello").output().await?;

Implementations§

Source§

impl Command

Source

pub fn new<S: AsRef<OsStr>>(program: S) -> Command

Constructs a new Command for launching program.

The initial configuration (the working directory and environment variables) is inherited from the current process.

§Examples
use async_process::Command;

let mut cmd = Command::new("ls");
Examples found in repository?
examples/timeout.rs (line 11)
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}
Source

pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command

Adds a single argument to pass to the program.

§Examples
use async_process::Command;

let mut cmd = Command::new("echo");
cmd.arg("hello");
cmd.arg("world");
Examples found in repository?
examples/timeout.rs (line 12)
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}
Source

pub fn args<I, S>(&mut self, args: I) -> &mut Command
where I: IntoIterator<Item = S>, S: AsRef<OsStr>,

Adds multiple arguments to pass to the program.

§Examples
use async_process::Command;

let mut cmd = Command::new("echo");
cmd.args(&["hello", "world"]);
Source

pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
where K: AsRef<OsStr>, V: AsRef<OsStr>,

Configures an environment variable for the new process.

Note that environment variable names are case-sensitive.

§Examples
use async_process::Command;

let mut cmd = Command::new("ls");
cmd.env("PATH", "/bin");
Source

pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
where I: IntoIterator<Item = (K, V)>, K: AsRef<OsStr>, V: AsRef<OsStr>,

Configures multiple environment variables for the new process.

Note that environment variable names are case-sensitive.

§Examples
use async_process::Command;

let mut cmd = Command::new("ls");
cmd.envs(vec![("PATH", "/bin"), ("TERM", "xterm-256color")]);
Source

pub fn get_args(&self) -> CommandArgs<'_> ⓘ

Gets an iterator of the arguments that will be passed to the program.

§Examples
use std::ffi::OsStr;
use async_process::Command;

let mut cmd = Command::new("echo");
cmd.arg("first").arg("second");
let args: Vec<&OsStr> = cmd.get_args().collect();
assert_eq!(args, &["first", "second"]);
Source

pub fn get_envs(&self) -> CommandEnvs<'_> ⓘ

Gets an iterator of the environment variables explicitly set for the child process.

§Examples
use std::ffi::OsStr;
use async_process::Command;

let mut cmd = Command::new("ls");
cmd.env("TERM", "dumb").env_remove("TZ");
let envs: Vec<(&OsStr, Option<&OsStr>)> = cmd.get_envs().collect();
assert_eq!(envs, &[
    (OsStr::new("TERM"), Some(OsStr::new("dumb"))),
    (OsStr::new("TZ"), None)
]);
Source

pub fn get_current_dir(&self) -> Option<&Path>

Gets the working directory for the child process.

This returns None if the working directory will not be changed.

§Examples
use std::path::Path;
use async_process::Command;

let mut cmd = Command::new("ls");
assert_eq!(cmd.get_current_dir(), None);
cmd.current_dir("/bin");
assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin")));
Source

pub fn get_program(&self) -> &OsStr

Gets the path to the program that was given to Command::new.

§Examples
use async_process::Command;

let cmd = Command::new("echo");
assert_eq!(cmd.get_program(), "echo");
Source

pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command

Removes an environment variable mapping.

§Examples
use async_process::Command;

let mut cmd = Command::new("ls");
cmd.env_remove("PATH");
Source

pub fn env_clear(&mut self) -> &mut Command

Removes all environment variable mappings.

§Examples
use async_process::Command;

let mut cmd = Command::new("ls");
cmd.env_clear();
Source

pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command

Configures the working directory for the new process.

§Examples
use async_process::Command;

let mut cmd = Command::new("ls");
cmd.current_dir("/");
Source

pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command

Configures the standard input (stdin) for the new process.

§Examples
use async_process::{Command, Stdio};

let mut cmd = Command::new("cat");
cmd.stdin(Stdio::null());
Source

pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command

Configures the standard output (stdout) for the new process.

§Examples
use async_process::{Command, Stdio};

let mut cmd = Command::new("ls");
cmd.stdout(Stdio::piped());
Examples found in repository?
examples/timeout.rs (line 13)
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}
Source

pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command

Configures the standard error (stderr) for the new process.

§Examples
use async_process::{Command, Stdio};

let mut cmd = Command::new("ls");
cmd.stderr(Stdio::piped());
Examples found in repository?
examples/timeout.rs (line 14)
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}
Source

pub fn reap_on_drop(&mut self, reap_on_drop: bool) -> &mut Command

Configures whether to reap the zombie process when Child is dropped.

When the process finishes, it becomes a “zombie” and some resources associated with it remain until Child::try_status(), Child::status(), or Child::output() collects its exit code.

If its exit code is never collected, the resources may leak forever. This crate has a background thread named “async-process” that collects such “zombie” processes and then “reaps” them, thus preventing the resource leaks.

The default value of this option is true.

§Examples
use async_process::{Command, Stdio};

let mut cmd = Command::new("cat");
cmd.reap_on_drop(false);
Source

pub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command

Configures whether to kill the process when Child is dropped.

The default value of this option is false.

§Examples
use async_process::{Command, Stdio};

let mut cmd = Command::new("cat");
cmd.kill_on_drop(true);
Source

pub fn spawn(&mut self) -> Result<Child>

Executes the command and returns the Child handle to it.

If not configured, stdin, stdout and stderr will be set to Stdio::inherit().

§Examples
use async_process::Command;

let child = Command::new("ls").spawn()?;
Examples found in repository?
examples/timeout.rs (line 15)
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}
Source

pub fn status(&mut self) -> impl Future<Output = Result<ExitStatus>>

Executes the command, waits for it to exit, and returns the exit status.

If not configured, stdin, stdout and stderr will be set to Stdio::inherit().

§Examples
use async_process::Command;

let status = Command::new("cp")
    .arg("a.txt")
    .arg("b.txt")
    .status()
    .await?;
Source

pub fn output(&mut self) -> impl Future<Output = Result<Output>>

Executes the command and collects its output.

If not configured, stdin will be set to Stdio::null(), and stdout and stderr will be set to Stdio::piped().

§Examples
use async_process::Command;

let output = Command::new("cat")
    .arg("a.txt")
    .output()
    .await?;

Trait Implementations§

Source§

impl CommandExt for Command

Source§

fn uid(&mut self, id: u32) -> &mut Command

Sets the child process’s user ID. This translates to a setuid call in the child process. Failure in the setuid call will cause the spawn to fail.
Source§

fn gid(&mut self, id: u32) -> &mut Command

Similar to uid, but sets the group ID of the child process. This has the same semantics as the uid field.
Source§

fn exec(&mut self) -> Error

Performs all the required setup by this Command, followed by calling the execvp syscall. Read more
Source§

fn arg0<S>(&mut self, arg: S) -> &mut Command
where S: AsRef<OsStr>,

Set executable argument Read more
Source§

impl Debug for Command

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<Command> for Command

Source§

fn from(inner: Command) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.