gobyexample/public/spawning-processes
2019-10-14 23:20:44 +03:00

268 lines
14 KiB
Plaintext
Generated
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>
<head>
<meta charset="utf-8">
<title>Go в примерах: Порождающие процессы (Spawning Processes)</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'http-servers';
}
if (e.key == "ArrowRight") {
window.location.href = 'execing-processes';
}
}
</script>
<body>
<div class="example" id="spawning-processes">
<h2><a href="./">Go в примерах</a>: Порождающие процессы (Spawning Processes)</h2>
<table>
<tr>
<td class="docs">
<p>Иногда наши программы Go должны порождать другие, не
Go процессы. Например, подсветка синтаксиса на этом
сайте <a href="https://github.com/mmcgrana/gobyexample/blob/master/tools/generate.go">реализуется</a>
путем запуска <a href="http://pygments.org/"><code>pygmentize</code></a>
процесса из программы Go. Давайте рассмотрим несколько
примеров порождающих процессов из Go.</p>
</td>
<td class="code empty leading">
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<a href="http://play.golang.org/p/2QNUQPuiFlR" target="_blank"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
<span class="s">&quot;fmt&quot;</span>
<span class="s">&quot;io/ioutil&quot;</span>
<span class="s">&quot;os/exec&quot;</span>
<span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Мы начнем с простой команды, которая не принимает
аргументов или ввода и просто печатает что-то на
стандартный вывод. Хелпер <code>exec.Command</code> создает
объект для представления этого внешнего процесса.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">dateCmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nx">Command</span><span class="p">(</span><span class="s">&quot;date&quot;</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p><code>.Output</code> - это еще один хелпер, который обрабатывает
общий случай запуска команды, ожидаетее завершения
и сбора выходных данных. Если ошибок не было, <code>dateOut</code>
будет содержать байты с информацией о дате.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">dateOut</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">dateCmd</span><span class="p">.</span><span class="nx">Output</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;&gt; date&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">dateOut</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Далее мы рассмотрим несколько более сложный случай,
когда мы направляем данные во внешний процесс на
его <code>stdin</code> и собираем результаты из его <code>stdout</code>.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">grepCmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nx">Command</span><span class="p">(</span><span class="s">&quot;grep&quot;</span><span class="p">,</span> <span class="s">&quot;hello&quot;</span><span class="p">)</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Здесь мы явно получаем каналы ввода-вывода,
запускаем процесс, записываем в него некоторые
входные данные, читаем полученный результат и,
наконец, ожидаем завершения процесса.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">grepIn</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">grepCmd</span><span class="p">.</span><span class="nx">StdinPipe</span><span class="p">()</span>
<span class="nx">grepOut</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">grepCmd</span><span class="p">.</span><span class="nx">StdoutPipe</span><span class="p">()</span>
<span class="nx">grepCmd</span><span class="p">.</span><span class="nx">Start</span><span class="p">()</span>
<span class="nx">grepIn</span><span class="p">.</span><span class="nx">Write</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="s">&quot;hello grep\ngoodbye grep&quot;</span><span class="p">))</span>
<span class="nx">grepIn</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span>
<span class="nx">grepBytes</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">ioutil</span><span class="p">.</span><span class="nx">ReadAll</span><span class="p">(</span><span class="nx">grepOut</span><span class="p">)</span>
<span class="nx">grepCmd</span><span class="p">.</span><span class="nx">Wait</span><span class="p">()</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Мы опускаем проверки ошибок в приведенном выше
примере, но вы можете использовать обычный шаблон
<code>if err != nil</code> для них. Мы также собираем только
результаты <code>StdoutPipe</code>, но вы можете собирать
<code>StderrPipe</code> точно таким же образом.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;&gt; grep hello&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">grepBytes</span><span class="p">))</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Обратите внимание, что при порождении команд нам
нужно предоставить явно разграниченный массив
команд и аргументов вместо возможности просто
передать одну строку командной строки.
Если вы хотите создать полную команду со строкой,
вы можете использовать опцию <code>-c</code> в <code>bash</code>:</p>
</td>
<td class="code">
<div class="highlight"><pre> <span class="nx">lsCmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nx">Command</span><span class="p">(</span><span class="s">&quot;bash&quot;</span><span class="p">,</span> <span class="s">&quot;-c&quot;</span><span class="p">,</span> <span class="s">&quot;ls -a -l -h&quot;</span><span class="p">)</span>
<span class="nx">lsOut</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">lsCmd</span><span class="p">.</span><span class="nx">Output</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;&gt; ls -a -l -h&quot;</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">lsOut</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
<p>Порожденные программы возвращают вывод, который
является таким же, как если бы мы запускали их
непосредственно из командной строки.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="gp">$</span> go run spawning-processes.go
<span class="gp">&gt;</span> date
<span class="go">Wed Oct 10 09:53:11 PDT 2012</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<div class="highlight"><pre><span class="gp">&gt;</span> grep hello
<span class="go">hello grep</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code">
<div class="highlight"><pre><span class="gp">&gt;</span> ls -a -l -h
<span class="go">drwxr-xr-x 4 mark 136B Oct 3 16:29 .</span>
<span class="go">drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..</span>
<span class="go">-rw-r--r-- 1 mark 1.3K Oct 3 16:28 spawning-processes.go</span>
</pre></div>
</td>
</tr>
</table>
<p class="next">
Следующий пример: <a href="execing-processes">Исполняющие процессы (Exec'ing Processes)</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/spawning-processes">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"io/ioutil\"\u000A \"os/exec\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' dateCmd := exec.Command(\"date\")\u000A');codeLines.push(' dateOut, err := dateCmd.Output()\u000A if err != nil {\u000A panic(err)\u000A }\u000A fmt.Println(\"\x3E date\")\u000A fmt.Println(string(dateOut))\u000A');codeLines.push(' grepCmd := exec.Command(\"grep\", \"hello\")\u000A');codeLines.push(' grepIn, _ := grepCmd.StdinPipe()\u000A grepOut, _ := grepCmd.StdoutPipe()\u000A grepCmd.Start()\u000A grepIn.Write([]byte(\"hello grep\\ngoodbye grep\"))\u000A grepIn.Close()\u000A grepBytes, _ := ioutil.ReadAll(grepOut)\u000A grepCmd.Wait()\u000A');codeLines.push(' fmt.Println(\"\x3E grep hello\")\u000A fmt.Println(string(grepBytes))\u000A');codeLines.push(' lsCmd := exec.Command(\"bash\", \"-c\", \"ls -a -l -h\")\u000A lsOut, err := lsCmd.Output()\u000A if err != nil {\u000A panic(err)\u000A }\u000A fmt.Println(\"\x3E ls -a -l -h\")\u000A fmt.Println(string(lsOut))\u000A}\u000A');codeLines.push('');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>