Files
rapr-rs/docs/tokio/process/index.html
T
Uttarayan Mondal d5ecda4c73 Initial docs commit
2021-03-15 01:27:34 +05:30

163 lines
20 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."><meta name="keywords" content="rust, rustlang, rust-lang, process"><title>tokio::process - Rust</title><link rel="stylesheet" type="text/css" href="../../normalize.css"><link rel="stylesheet" type="text/css" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../../ayu.css" disabled ><script id="default-settings"></script><script src="../../storage.js"></script><noscript><link rel="stylesheet" href="../../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../../favicon.svg">
<link rel="alternate icon" type="image/png" href="../../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../../tokio/index.html'><div class='logo-container rust-logo'><img src='../../rust-logo.png' alt='logo'></div></a><p class="location">Module process</p><div class="sidebar-elems"><div class="block items"><ul><li><a href="#structs">Structs</a></li></ul></div><p class="location"><a href="../index.html">tokio</a></p><div id="sidebar-vars" data-name="process" data-ty="mod" data-relpath="../"></div><script defer src="../sidebar-items.js"></script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<a id="settings-menu" href="../../settings.html"><img src="../../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><h1 class="fqn"><span class="in-band">Module <a href="../index.html">tokio</a>::<wbr><a class="mod" href="">process</a></span><span class="out-of-band"><span id="render-detail"><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span><a class="srclink" href="../../src/tokio/process/mod.rs.html#1-1384" title="goto source code">[src]</a></span></h1><div class="docblock"><p>An implementation of asynchronous process management for Tokio.</p>
<p>This module provides a <a href="../../tokio/process/struct.Command.html"><code>Command</code></a> struct that imitates the interface of the
<a href="https://doc.rust-lang.org/nightly/std/process/struct.Command.html"><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>
<h1 id="examples" class="section-header"><a href="#examples">Examples</a></h1>
<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">
<span class="kw">use</span> <span class="ident">tokio</span>::<span class="ident">process</span>::<span class="ident">Command</span>;
<span class="attribute">#[<span class="ident">tokio</span>::<span class="ident">main</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">main</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Box</span><span class="op">&lt;</span><span class="kw">dyn</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="comment">// The usage is similar as with the standard library&#39;s `Command` type</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">child</span> <span class="op">=</span> <span class="ident">Command</span>::<span class="ident">new</span>(<span class="string">&quot;echo&quot;</span>)
.<span class="ident">arg</span>(<span class="string">&quot;hello&quot;</span>)
.<span class="ident">arg</span>(<span class="string">&quot;world&quot;</span>)
.<span class="ident">spawn</span>()
.<span class="ident">expect</span>(<span class="string">&quot;failed to spawn&quot;</span>);
<span class="comment">// Await until the command completes</span>
<span class="kw">let</span> <span class="ident">status</span> <span class="op">=</span> <span class="ident">child</span>.<span class="ident">wait</span>().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;the command exited with: {}&quot;</span>, <span class="ident">status</span>);
<span class="prelude-val">Ok</span>(())
}</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">
<span class="kw">use</span> <span class="ident">tokio</span>::<span class="ident">process</span>::<span class="ident">Command</span>;
<span class="attribute">#[<span class="ident">tokio</span>::<span class="ident">main</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">main</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Box</span><span class="op">&lt;</span><span class="kw">dyn</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="comment">// Like above, but use `output` which returns a future instead of</span>
<span class="comment">// immediately returning the `Child`.</span>
<span class="kw">let</span> <span class="ident">output</span> <span class="op">=</span> <span class="ident">Command</span>::<span class="ident">new</span>(<span class="string">&quot;echo&quot;</span>).<span class="ident">arg</span>(<span class="string">&quot;hello&quot;</span>).<span class="ident">arg</span>(<span class="string">&quot;world&quot;</span>)
.<span class="ident">output</span>();
<span class="kw">let</span> <span class="ident">output</span> <span class="op">=</span> <span class="ident">output</span>.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">output</span>.<span class="ident">status</span>.<span class="ident">success</span>());
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">output</span>.<span class="ident">stdout</span>, <span class="string">b&quot;hello world\n&quot;</span>);
<span class="prelude-val">Ok</span>(())
}</pre></div>
<p>We can also read input line by line.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">tokio</span>::<span class="ident">io</span>::{<span class="ident">BufReader</span>, <span class="ident">AsyncBufReadExt</span>};
<span class="kw">use</span> <span class="ident">tokio</span>::<span class="ident">process</span>::<span class="ident">Command</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">process</span>::<span class="ident">Stdio</span>;
<span class="attribute">#[<span class="ident">tokio</span>::<span class="ident">main</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">main</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Box</span><span class="op">&lt;</span><span class="kw">dyn</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">cmd</span> <span class="op">=</span> <span class="ident">Command</span>::<span class="ident">new</span>(<span class="string">&quot;cat&quot;</span>);
<span class="comment">// Specify that we want the command&#39;s standard output piped back to us.</span>
<span class="comment">// By default, standard input/output/error will be inherited from the</span>
<span class="comment">// current process (for example, this means that standard input will</span>
<span class="comment">// come from the keyboard and standard output/error will go directly to</span>
<span class="comment">// the terminal if this process is invoked from the command line).</span>
<span class="ident">cmd</span>.<span class="ident">stdout</span>(<span class="ident">Stdio</span>::<span class="ident">piped</span>());
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">child</span> <span class="op">=</span> <span class="ident">cmd</span>.<span class="ident">spawn</span>()
.<span class="ident">expect</span>(<span class="string">&quot;failed to spawn command&quot;</span>);
<span class="kw">let</span> <span class="ident">stdout</span> <span class="op">=</span> <span class="ident">child</span>.<span class="ident">stdout</span>.<span class="ident">take</span>()
.<span class="ident">expect</span>(<span class="string">&quot;child did not have a handle to stdout&quot;</span>);
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">reader</span> <span class="op">=</span> <span class="ident">BufReader</span>::<span class="ident">new</span>(<span class="ident">stdout</span>).<span class="ident">lines</span>();
<span class="comment">// Ensure the child process is spawned in the runtime so it can</span>
<span class="comment">// make progress on its own while we await for any output.</span>
<span class="ident">tokio</span>::<span class="ident">spawn</span>(<span class="kw">async</span> <span class="kw">move</span> {
<span class="kw">let</span> <span class="ident">status</span> <span class="op">=</span> <span class="ident">child</span>.<span class="ident">wait</span>().<span class="kw">await</span>
.<span class="ident">expect</span>(<span class="string">&quot;child process encountered an error&quot;</span>);
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;child status was: {}&quot;</span>, <span class="ident">status</span>);
});
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">line</span>) <span class="op">=</span> <span class="ident">reader</span>.<span class="ident">next_line</span>().<span class="kw">await</span><span class="question-mark">?</span> {
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;Line: {}&quot;</span>, <span class="ident">line</span>);
}
<span class="prelude-val">Ok</span>(())
}</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">
<span class="kw">use</span> <span class="ident">tokio</span>::<span class="ident">join</span>;
<span class="kw">use</span> <span class="ident">tokio</span>::<span class="ident">process</span>::<span class="ident">Command</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">convert</span>::<span class="ident">TryInto</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">process</span>::<span class="ident">Stdio</span>;
<span class="attribute">#[<span class="ident">tokio</span>::<span class="ident">main</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">main</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Box</span><span class="op">&lt;</span><span class="kw">dyn</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">echo</span> <span class="op">=</span> <span class="ident">Command</span>::<span class="ident">new</span>(<span class="string">&quot;echo&quot;</span>)
.<span class="ident">arg</span>(<span class="string">&quot;hello world!&quot;</span>)
.<span class="ident">stdout</span>(<span class="ident">Stdio</span>::<span class="ident">piped</span>())
.<span class="ident">spawn</span>()
.<span class="ident">expect</span>(<span class="string">&quot;failed to spawn echo&quot;</span>);
<span class="kw">let</span> <span class="ident">tr_stdin</span>: <span class="ident">Stdio</span> <span class="op">=</span> <span class="ident">echo</span>
.<span class="ident">stdout</span>
.<span class="ident">take</span>()
.<span class="ident">unwrap</span>()
.<span class="ident">try_into</span>()
.<span class="ident">expect</span>(<span class="string">&quot;failed to convert to Stdio&quot;</span>);
<span class="kw">let</span> <span class="ident">tr</span> <span class="op">=</span> <span class="ident">Command</span>::<span class="ident">new</span>(<span class="string">&quot;tr&quot;</span>)
.<span class="ident">arg</span>(<span class="string">&quot;a-z&quot;</span>)
.<span class="ident">arg</span>(<span class="string">&quot;A-Z&quot;</span>)
.<span class="ident">stdin</span>(<span class="ident">tr_stdin</span>)
.<span class="ident">stdout</span>(<span class="ident">Stdio</span>::<span class="ident">piped</span>())
.<span class="ident">spawn</span>()
.<span class="ident">expect</span>(<span class="string">&quot;failed to spawn tr&quot;</span>);
<span class="kw">let</span> (<span class="ident">echo_result</span>, <span class="ident">tr_output</span>) <span class="op">=</span> <span class="macro">join</span><span class="macro">!</span>(<span class="ident">echo</span>.<span class="ident">wait</span>(), <span class="ident">tr</span>.<span class="ident">wait_with_output</span>());
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">echo_result</span>.<span class="ident">unwrap</span>().<span class="ident">success</span>());
<span class="kw">let</span> <span class="ident">tr_output</span> <span class="op">=</span> <span class="ident">tr_output</span>.<span class="ident">expect</span>(<span class="string">&quot;failed to await tr&quot;</span>);
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">tr_output</span>.<span class="ident">status</span>.<span class="ident">success</span>());
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">tr_output</span>.<span class="ident">stdout</span>, <span class="string">b&quot;HELLO WORLD!\n&quot;</span>);
<span class="prelude-val">Ok</span>(())
}</pre></div>
<h1 id="caveats" class="section-header"><a href="#caveats">Caveats</a></h1><h2 id="droppingcancellation" class="section-header"><a href="#droppingcancellation">Dropping/Cancellation</a></h2>
<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="../../tokio/process/struct.Command.html#method.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>
<h2 id="unix-processes" class="section-header"><a href="#unix-processes">Unix Processes</a></h2>
<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 regards
how quickly or how often this procedure will take place.</p>
<p>It is recommended to avoid dropping a <a href="../../tokio/process/struct.Child.html"><code>Child</code></a> process handle before it has been
fully <code>await</code>ed if stricter cleanup guarantees are required.</p>
</div><h2 id="structs" class="section-header"><a href="#structs">Structs</a></h2>
<table><tr class="module-item"><td><a class="struct" href="struct.Child.html" title="tokio::process::Child struct">Child</a></td><td class="docblock-short"><p>Representation of a child process spawned onto an event loop.</p>
</td></tr><tr class="module-item"><td><a class="struct" href="struct.ChildStderr.html" title="tokio::process::ChildStderr struct">ChildStderr</a></td><td class="docblock-short"><p>The standard error stream for spawned children.</p>
</td></tr><tr class="module-item"><td><a class="struct" href="struct.ChildStdin.html" title="tokio::process::ChildStdin struct">ChildStdin</a></td><td class="docblock-short"><p>The standard input stream for spawned children.</p>
</td></tr><tr class="module-item"><td><a class="struct" href="struct.ChildStdout.html" title="tokio::process::ChildStdout struct">ChildStdout</a></td><td class="docblock-short"><p>The standard output stream for spawned children.</p>
</td></tr><tr class="module-item"><td><a class="struct" href="struct.Command.html" title="tokio::process::Command struct">Command</a></td><td class="docblock-short"><p>This structure mimics the API of <a href="https://doc.rust-lang.org/nightly/std/process/struct.Command.html"><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="../../tokio/process/struct.Command.html#method.spawn">spawn</a>, <a href="../../tokio/process/struct.Command.html#method.status">status</a>, and
<a href="../../tokio/process/struct.Command.html#method.output">output</a>.</p>
</td></tr></table></section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../../" data-current-crate="tokio"></div>
<script src="../../main.js"></script><script defer src="../../search-index.js"></script></body></html>