Files
GopherGate/target/doc/tokio/process/index.html
2026-02-26 12:00:21 -05:00

197 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="An implementation of asynchronous process management for Tokio."><title>tokio::process - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="tokio" data-themes="" data-resource-suffix="" data-rustdoc-version="1.93.1 (01f6ddf75 2026-02-11) (Arch Linux rust 1:1.93.1-1)" data-channel="1.93.1" data-search-js="search-9e2438ea.js" data-stringdex-js="stringdex-a3946164.js" data-settings-js="settings-c38705f0.js" ><script src="../../static.files/storage-e2aeef58.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../static.files/main-a410ff4d.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">Module process</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../tokio/index.html">tokio</a><span class="version">1.49.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module process</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#examples" title="Examples">Examples</a></li><li><a href="#caveats" title="Caveats">Caveats</a><ul><li><a href="#droppingcancellation" title="Dropping/Cancellation">Dropping/Cancellation</a></li><li><a href="#unix-processes" title="Unix Processes">Unix Processes</a></li></ul></li></ul><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="../index.html">In crate tokio</a></h2></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="../index.html">tokio</a></div><h1>Module <span>process</span>&nbsp;<button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../src/tokio/process/mod.rs.html#1-1854">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>An implementation of asynchronous process management for Tokio.</p>
<p>This module provides a <a href="struct.Command.html" title="struct tokio::process::Command"><code>Command</code></a> struct that imitates the interface of the
<a href="https://doc.rust-lang.org/1.93.1/std/process/struct.Command.html" title="struct std::process::Command"><code>std::process::Command</code></a> type in the standard library, but provides asynchronous versions of
functions that create processes. These functions (<code>spawn</code>, <code>status</code>, <code>output</code> and their
variants) return “future aware” types that interoperate with Tokio. The asynchronous process
support is provided through signal handling on Unix and system APIs on Windows.</p>
<h2 id="examples"><a class="doc-anchor" href="#examples">§</a>Examples</h2>
<p>Heres an example program which will spawn <code>echo hello world</code> and then wait
for it complete.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::process::Command;
<span class="attr">#[tokio::main]
</span><span class="kw">async fn </span>main() -&gt; <span class="prelude-ty">Result</span>&lt;(), Box&lt;<span class="kw">dyn </span>std::error::Error&gt;&gt; {
<span class="comment">// The usage is similar as with the standard library's `Command` type
</span><span class="kw">let </span><span class="kw-2">mut </span>child = Command::new(<span class="string">"echo"</span>)
.arg(<span class="string">"hello"</span>)
.arg(<span class="string">"world"</span>)
.spawn()
.expect(<span class="string">"failed to spawn"</span>);
<span class="comment">// Await until the command completes
</span><span class="kw">let </span>status = child.wait().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="macro">println!</span>(<span class="string">"the command exited with: {}"</span>, status);
<span class="prelude-val">Ok</span>(())
}</code></pre></div>
<p>Next, lets take a look at an example where we not only spawn <code>echo hello world</code> but we also capture its output.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::process::Command;
<span class="attr">#[tokio::main]
</span><span class="kw">async fn </span>main() -&gt; <span class="prelude-ty">Result</span>&lt;(), Box&lt;<span class="kw">dyn </span>std::error::Error&gt;&gt; {
<span class="comment">// Like above, but use `output` which returns a future instead of
// immediately returning the `Child`.
</span><span class="kw">let </span>output = Command::new(<span class="string">"echo"</span>).arg(<span class="string">"hello"</span>).arg(<span class="string">"world"</span>)
.output();
<span class="kw">let </span>output = output.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="macro">assert!</span>(output.status.success());
<span class="macro">assert_eq!</span>(output.stdout, <span class="string">b"hello world\n"</span>);
<span class="prelude-val">Ok</span>(())
}</code></pre></div>
<p>We can also read input line by line.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::io::{BufReader, AsyncBufReadExt};
<span class="kw">use </span>tokio::process::Command;
<span class="kw">use </span>std::process::Stdio;
<span class="attr">#[tokio::main]
</span><span class="kw">async fn </span>main() -&gt; <span class="prelude-ty">Result</span>&lt;(), Box&lt;<span class="kw">dyn </span>std::error::Error&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cmd = Command::new(<span class="string">"cat"</span>);
<span class="comment">// Specify that we want the command's standard output piped back to us.
// By default, standard input/output/error will be inherited from the
// current process (for example, this means that standard input will
// come from the keyboard and standard output/error will go directly to
// the terminal if this process is invoked from the command line).
</span>cmd.stdout(Stdio::piped());
<span class="kw">let </span><span class="kw-2">mut </span>child = cmd.spawn()
.expect(<span class="string">"failed to spawn command"</span>);
<span class="kw">let </span>stdout = child.stdout.take()
.expect(<span class="string">"child did not have a handle to stdout"</span>);
<span class="kw">let </span><span class="kw-2">mut </span>reader = BufReader::new(stdout).lines();
<span class="comment">// Ensure the child process is spawned in the runtime so it can
// make progress on its own while we await for any output.
</span>tokio::spawn(<span class="kw">async move </span>{
<span class="kw">let </span>status = child.wait().<span class="kw">await
</span>.expect(<span class="string">"child process encountered an error"</span>);
<span class="macro">println!</span>(<span class="string">"child status was: {}"</span>, status);
});
<span class="kw">while let </span><span class="prelude-val">Some</span>(line) = reader.next_line().<span class="kw">await</span><span class="question-mark">? </span>{
<span class="macro">println!</span>(<span class="string">"Line: {}"</span>, line);
}
<span class="prelude-val">Ok</span>(())
}</code></pre></div>
<p>Here is another example using <code>sort</code> writing into the child process
standard input, capturing the output of the sorted text.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::io::AsyncWriteExt;
<span class="kw">use </span>tokio::process::Command;
<span class="kw">use </span>std::process::Stdio;
<span class="attr">#[tokio::main]
</span><span class="kw">async fn </span>main() -&gt; <span class="prelude-ty">Result</span>&lt;(), Box&lt;<span class="kw">dyn </span>std::error::Error&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cmd = Command::new(<span class="string">"sort"</span>);
<span class="comment">// Specifying that we want pipe both the output and the input.
// Similarly to capturing the output, by configuring the pipe
// to stdin it can now be used as an asynchronous writer.
</span>cmd.stdout(Stdio::piped());
cmd.stdin(Stdio::piped());
<span class="kw">let </span><span class="kw-2">mut </span>child = cmd.spawn().expect(<span class="string">"failed to spawn command"</span>);
<span class="comment">// These are the animals we want to sort
</span><span class="kw">let </span>animals: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span>str] = <span class="kw-2">&amp;</span>[<span class="string">"dog"</span>, <span class="string">"bird"</span>, <span class="string">"frog"</span>, <span class="string">"cat"</span>, <span class="string">"fish"</span>];
<span class="kw">let </span><span class="kw-2">mut </span>stdin = child
.stdin
.take()
.expect(<span class="string">"child did not have a handle to stdin"</span>);
<span class="comment">// Write our animals to the child process
// Note that the behavior of `sort` is to buffer _all input_ before writing any output.
// In the general sense, it is recommended to write to the child in a separate task as
// awaiting its exit (or output) to avoid deadlocks (for example, the child tries to write
// some output but gets stuck waiting on the parent to read from it, meanwhile the parent
// is stuck waiting to write its input completely before reading the output).
</span>stdin
.write(animals.join(<span class="string">"\n"</span>).as_bytes())
.<span class="kw">await
</span>.expect(<span class="string">"could not write to stdin"</span>);
<span class="comment">// We drop the handle here which signals EOF to the child process.
// This tells the child process that it there is no more data on the pipe.
</span>drop(stdin);
<span class="kw">let </span>op = child.wait_with_output().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="comment">// Results should come back in sorted order
</span><span class="macro">assert_eq!</span>(op.stdout, <span class="string">"bird\ncat\ndog\nfish\nfrog\n"</span>.as_bytes());
<span class="prelude-val">Ok</span>(())
}</code></pre></div>
<p>With some coordination, we can also pipe the output of one command into
another.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::join;
<span class="kw">use </span>tokio::process::Command;
<span class="kw">use </span>std::process::Stdio;
<span class="attr">#[tokio::main]
</span><span class="kw">async fn </span>main() -&gt; <span class="prelude-ty">Result</span>&lt;(), Box&lt;<span class="kw">dyn </span>std::error::Error&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>echo = Command::new(<span class="string">"echo"</span>)
.arg(<span class="string">"hello world!"</span>)
.stdout(Stdio::piped())
.spawn()
.expect(<span class="string">"failed to spawn echo"</span>);
<span class="kw">let </span>tr_stdin: Stdio = echo
.stdout
.take()
.unwrap()
.try_into()
.expect(<span class="string">"failed to convert to Stdio"</span>);
<span class="kw">let </span>tr = Command::new(<span class="string">"tr"</span>)
.arg(<span class="string">"a-z"</span>)
.arg(<span class="string">"A-Z"</span>)
.stdin(tr_stdin)
.stdout(Stdio::piped())
.spawn()
.expect(<span class="string">"failed to spawn tr"</span>);
<span class="kw">let </span>(echo_result, tr_output) = <span class="macro">join!</span>(echo.wait(), tr.wait_with_output());
<span class="macro">assert!</span>(echo_result.unwrap().success());
<span class="kw">let </span>tr_output = tr_output.expect(<span class="string">"failed to await tr"</span>);
<span class="macro">assert!</span>(tr_output.status.success());
<span class="macro">assert_eq!</span>(tr_output.stdout, <span class="string">b"HELLO WORLD!\n"</span>);
<span class="prelude-val">Ok</span>(())
}</code></pre></div><h2 id="caveats"><a class="doc-anchor" href="#caveats">§</a>Caveats</h2><h3 id="droppingcancellation"><a class="doc-anchor" href="#droppingcancellation">§</a>Dropping/Cancellation</h3>
<p>Similar to the behavior to the standard library, and unlike the futures
paradigm of dropping-implies-cancellation, a spawned process will, by
default, continue to execute even after the <code>Child</code> handle has been dropped.</p>
<p>The <a href="struct.Command.html#method.kill_on_drop" title="method tokio::process::Command::kill_on_drop"><code>Command::kill_on_drop</code></a> method can be used to modify this behavior
and kill the child process if the <code>Child</code> wrapper is dropped before it
has exited.</p>
<h3 id="unix-processes"><a class="doc-anchor" href="#unix-processes">§</a>Unix Processes</h3>
<p>On Unix platforms processes must be “reaped” by their parent process after
they have exited in order to release all OS resources. A child process which
has exited, but has not yet been reaped by its parent is considered a “zombie”
process. Such processes continue to count against limits imposed by the system,
and having too many zombie processes present can prevent additional processes
from being spawned.</p>
<p>The tokio runtime will, on a best-effort basis, attempt to reap and clean up
any process which it has spawned. No additional guarantees are made with regard to
how quickly or how often this procedure will take place.</p>
<p>It is recommended to avoid dropping a <a href="struct.Child.html" title="struct tokio::process::Child"><code>Child</code></a> process handle before it has been
fully <code>await</code>ed if stricter cleanup guarantees are required.</p>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.Child.html" title="struct tokio::process::Child">Child</a></dt><dd>Representation of a child process spawned onto an event loop.</dd><dt><a class="struct" href="struct.ChildStderr.html" title="struct tokio::process::ChildStderr">Child<wbr>Stderr</a></dt><dd>The standard error stream for spawned children.</dd><dt><a class="struct" href="struct.ChildStdin.html" title="struct tokio::process::ChildStdin">Child<wbr>Stdin</a></dt><dd>The standard input stream for spawned children.</dd><dt><a class="struct" href="struct.ChildStdout.html" title="struct tokio::process::ChildStdout">Child<wbr>Stdout</a></dt><dd>The standard output stream for spawned children.</dd><dt><a class="struct" href="struct.Command.html" title="struct tokio::process::Command">Command</a></dt><dd>This structure mimics the API of <a href="https://doc.rust-lang.org/1.93.1/std/process/struct.Command.html" title="struct std::process::Command"><code>std::process::Command</code></a> found in the standard library, but
replaces functions that create a process with an asynchronous variant. The main provided
asynchronous functions are <a href="struct.Command.html#method.spawn" title="method tokio::process::Command::spawn">spawn</a>, <a href="struct.Command.html#method.status" title="method tokio::process::Command::status">status</a>, and
<a href="struct.Command.html#method.output" title="method tokio::process::Command::output">output</a>.</dd></dl></section></div></main></body></html>