forked from mmcgrana/gobyexample
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspawning-processes
256 lines (204 loc) · 11.7 KB
/
spawning-processes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Go by Example: Spawning Processes</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'context';
}
if (e.key == "ArrowRight") {
window.location.href = 'execing-processes';
}
}
</script>
<body>
<div class="example" id="spawning-processes">
<h2><a href="./">Go by Example</a>: Spawning Processes</h2>
<table>
<tr>
<td class="docs">
<p>Sometimes our Go programs need to spawn other, non-Go
processes.</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/s-T7gxeD7hH"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><span class="kn">import</span> <span class="p">(</span>
<span class="s">"fmt"</span>
<span class="s">"io"</span>
<span class="s">"os/exec"</span>
<span class="p">)</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
<p>We’ll start with a simple command that takes no
arguments or input and just prints something to
stdout. The <code>exec.Command</code> helper creates an object
to represent this external process.</p>
</td>
<td class="code leading">
<pre class="chroma">
<span class="nx">dateCmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"date"</span><span class="p">)</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
<p><code>.Output</code> is another helper that handles the common
case of running a command, waiting for it to finish,
and collecting its output. If there were no errors,
<code>dateOut</code> will hold bytes with the date info.</p>
</td>
<td class="code leading">
<pre class="chroma">
<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="nf">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="nf">Println</span><span class="p">(</span><span class="s">"> date"</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">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>
</td>
</tr>
<tr>
<td class="docs">
<p>Next we’ll look at a slightly more involved case
where we pipe data to the external process on its
<code>stdin</code> and collect the results from its <code>stdout</code>.</p>
</td>
<td class="code leading">
<pre class="chroma">
<span class="nx">grepCmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"grep"</span><span class="p">,</span> <span class="s">"hello"</span><span class="p">)</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
<p>Here we explicitly grab input/output pipes, start
the process, write some input to it, read the
resulting output, and finally wait for the process
to exit.</p>
</td>
<td class="code leading">
<pre class="chroma">
<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="nf">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="nf">StdoutPipe</span><span class="p">()</span>
<span class="nx">grepCmd</span><span class="p">.</span><span class="nf">Start</span><span class="p">()</span>
<span class="nx">grepIn</span><span class="p">.</span><span class="nf">Write</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="s">"hello grep\ngoodbye grep"</span><span class="p">))</span>
<span class="nx">grepIn</span><span class="p">.</span><span class="nf">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">io</span><span class="p">.</span><span class="nf">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="nf">Wait</span><span class="p">()</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
<p>We omitted error checks in the above example, but
you could use the usual <code>if err != nil</code> pattern for
all of them. We also only collect the <code>StdoutPipe</code>
results, but you could collect the <code>StderrPipe</code> in
exactly the same way.</p>
</td>
<td class="code leading">
<pre class="chroma">
<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"> grep hello"</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">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>
</td>
</tr>
<tr>
<td class="docs">
<p>Note that when spawning commands we need to
provide an explicitly delineated command and
argument array, vs. being able to just pass in one
command-line string. If you want to spawn a full
command with a string, you can use <code>bash</code>’s <code>-c</code>
option:</p>
</td>
<td class="code">
<pre class="chroma">
<span class="nx">lsCmd</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">"bash"</span><span class="p">,</span> <span class="s">"-c"</span><span class="p">,</span> <span class="s">"ls -a -l -h"</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="nf">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="nf">Println</span><span class="p">(</span><span class="s">"> ls -a -l -h"</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">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>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
<p>The spawned programs return output that is the same
as if we had run them directly from the command-line.</p>
</td>
<td class="code leading">
<pre class="chroma">
<span class="gp">$</span> go run spawning-processes.go
<span class="gp">></span> date
<span class="go">Wed Oct 10 09:53:11 PDT 2012</span></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><span class="gp">></span> grep hello
<span class="go">hello grep</span></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code">
<pre class="chroma"><span class="gp">></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>
</td>
</tr>
</table>
<p class="next">
Next example: <a href="execing-processes">Exec'ing Processes</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> and <a href="https://eli.thegreenplace.net">Eli Bendersky</a> | <a href="https://github.com/mmcgrana/gobyexample">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\"\u000A \"os/exec\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' dateCmd :\u003D exec.Command(\"date\")\u000A');codeLines.push(' dateOut, err :\u003D dateCmd.Output()\u000A if err !\u003D nil {\u000A panic(err)\u000A }\u000A fmt.Println(\"\u003E date\")\u000A fmt.Println(string(dateOut))\u000A');codeLines.push(' grepCmd :\u003D exec.Command(\"grep\", \"hello\")\u000A');codeLines.push(' grepIn, _ :\u003D grepCmd.StdinPipe()\u000A grepOut, _ :\u003D grepCmd.StdoutPipe()\u000A grepCmd.Start()\u000A grepIn.Write([]byte(\"hello grep\\ngoodbye grep\"))\u000A grepIn.Close()\u000A grepBytes, _ :\u003D io.ReadAll(grepOut)\u000A grepCmd.Wait()\u000A');codeLines.push(' fmt.Println(\"\u003E grep hello\")\u000A fmt.Println(string(grepBytes))\u000A');codeLines.push(' lsCmd :\u003D exec.Command(\"bash\", \"-c\", \"ls -a -l -h\")\u000A lsOut, err :\u003D lsCmd.Output()\u000A if err !\u003D nil {\u000A panic(err)\u000A }\u000A fmt.Println(\"\u003E 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>