Improve spawning-process example with error-checking

This commit is contained in:
Eli Bendersky 2022-05-06 10:16:02 -07:00
parent 6b91c38bb3
commit 9deadb76ae
4 changed files with 67 additions and 16 deletions

View File

@ -17,10 +17,10 @@ func main() {
// to represent this external process.
dateCmd := exec.Command("date")
// `.Output` 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,
// `dateOut` will hold bytes with the date info.
// The `Output` method runs the command, waits for it
// to finish and collects its standard output.
// If there were no errors, `dateOut` will hold bytes
// with the date info.
dateOut, err := dateCmd.Output()
if err != nil {
panic(err)
@ -28,6 +28,23 @@ func main() {
fmt.Println("> date")
fmt.Println(string(dateOut))
// `Output` and other methods of `Command` will return
// `*exec.Error` if there was a problem executing the
// command (e.g. wrong path), and `*exec.ExitError`
// if the command ran but exited with a non-zero return
// code.
_, err = exec.Command("date", "-x").Output()
if err != nil {
switch e := err.(type) {
case *exec.Error:
fmt.Println("failed executing:", err)
case *exec.ExitError:
fmt.Println("command exit rc =", e.ExitCode())
default:
panic(err)
}
}
// Next we'll look at a slightly more involved case
// where we pipe data to the external process on its
// `stdin` and collect the results from its `stdout`.

View File

@ -1,2 +1,2 @@
aaedc48f74409cef2b8e9ad624aa1c4639ce630d
s-T7gxeD7hH
5303cfb969de556a875db17972b4107b6f70ba10
rmnQdR-dMWU

View File

@ -2,8 +2,11 @@
# as if we had run them directly from the command-line.
$ go run spawning-processes.go
> date
Wed Oct 10 09:53:11 PDT 2012
Thu 05 May 2022 10:10:12 PM PDT
# date doesn't have a `-x` flag so it will exit with
# an error message and non-zero return code.
command exited with rc = 1
> grep hello
hello grep

View File

@ -42,7 +42,7 @@ processes.</p>
</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" />
<a href="http://play.golang.org/p/rmnQdR-dMWU"><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>
@ -92,10 +92,10 @@ to represent this external process.</p>
<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>
<p>The <code>Output</code> method runs the command, waits for it
to finish and collects its standard output.
If there were no errors, <code>dateOut</code> will hold bytes
with the date info.</p>
</td>
<td class="code leading">
@ -111,6 +111,33 @@ and collecting its output. If there were no errors,
</td>
</tr>
<tr>
<td class="docs">
<p><code>Output</code> and other methods of <code>Command</code> will return
<code>*exec.Error</code> if there was a problem executing the
command (e.g. wrong path), and <code>*exec.ExitError</code>
if the command ran but exited with a non-zero return
code.</p>
</td>
<td class="code leading">
<pre class="chroma">
<span class="nx">_</span><span class="p">,</span> <span class="nx">err</span> <span class="p">=</span> <span class="nx">exec</span><span class="p">.</span><span class="nf">Command</span><span class="p">(</span><span class="s">&#34;date&#34;</span><span class="p">,</span> <span class="s">&#34;-x&#34;</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="k">switch</span> <span class="nx">e</span> <span class="o">:=</span> <span class="nx">err</span><span class="p">.(</span><span class="kd">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="o">*</span><span class="nx">exec</span><span class="p">.</span><span class="nx">Error</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">&#34;failed executing:&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="k">case</span> <span class="o">*</span><span class="nx">exec</span><span class="p">.</span><span class="nx">ExitError</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">&#34;command exit rc =&#34;</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nf">ExitCode</span><span class="p">())</span>
<span class="k">default</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="p">}</span>
</pre>
</td>
</tr>
<tr>
<td class="docs">
<p>Next we&rsquo;ll look at a slightly more involved case
@ -206,17 +233,21 @@ as if we had run them directly from the command-line.</p>
<pre class="chroma">
<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>
<span class="go">Thu 05 May 2022 10:10:12 PM PDT</span></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>date doesn&rsquo;t have a <code>-x</code> flag so it will exit with
an error message and non-zero return code.</p>
</td>
<td class="code leading">
<pre class="chroma"><span class="gp">&gt;</span> grep hello
<pre class="chroma">
<span class="go">command exited with rc = 1
</span><span class="go"></span><span class="gp">&gt;</span> grep hello
<span class="go">hello grep</span></pre>
</td>
</tr>
@ -249,7 +280,7 @@ as if we had run them directly from the command-line.</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('');
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(' _, err \u003D exec.Command(\"date\", \"-x\").Output()\u000A if err !\u003D nil {\u000A switch e :\u003D err.(type) {\u000A case *exec.Error:\u000A fmt.Println(\"failed executing:\", err)\u000A case *exec.ExitError:\u000A fmt.Println(\"command exit rc \u003D\", e.ExitCode())\u000A default:\u000A panic(err)\u000A }\u000A }\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>