gobyexample/public/execing-processes
Hana 9e216da9ef go.mod: add go.mod and move pygments to third_party
After go1.16, go will use module mode by default,
even when the repository is checked out under GOPATH
or in a one-off directory. Add go.mod, go.sum to keep
this repo buildable without opting out of the module
mode.

> go mod init github.com/mmcgrana/gobyexample
> go mod tidy
> go mod vendor

In module mode, the 'vendor' directory is special
and its contents will be actively maintained by the
go command. pygments aren't the dependency the go will
know about, so it will delete the contents from vendor
directory. Move it to `third_party` directory now.

And, vendor the blackfriday package.

Note: the tutorial contents are not affected by the
change in go1.16 because all the examples in this
tutorial ask users to run the go command with the
explicit list of files to be compiled (e.g.
`go run hello-world.go` or `go build command-line-arguments.go`).
When the source list is provided, the go command does
not have to compute the build list and whether it's
running in GOPATH mode or module mode becomes irrelevant.
2021-02-15 16:45:26 -05:00

211 lines
7.9 KiB
Plaintext
Generated

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Go by Example: Exec'ing Processes</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'spawning-processes';
}
if (e.key == "ArrowRight") {
window.location.href = 'signals';
}
}
</script>
<body>
<div class="example" id="execing-processes">
<h2><a href="./">Go by Example</a>: Exec'ing Processes</h2>
<table>
<tr>
<td class="docs">
<p>In the previous example we looked at
<a href="spawning-processes">spawning external processes</a>. We
do this when we need an external process accessible to
a running Go process. Sometimes we just want to
completely replace the current Go process with another
(perhaps non-Go) one. To do this we&rsquo;ll use Go&rsquo;s
implementation of the classic
<a href="http://en.wikipedia.org/wiki/Exec_(operating_system)"><code>exec</code></a>
function.</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/T3da5euHejy"><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;os&quot;</span>
<span class="s">&quot;os/exec&quot;</span>
<span class="s">&quot;syscall&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>For our example we&rsquo;ll exec <code>ls</code>. Go requires an
absolute path to the binary we want to execute, so
we&rsquo;ll use <code>exec.LookPath</code> to find it (probably
<code>/bin/ls</code>).</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">binary</span><span class="p">,</span> <span class="nx">lookErr</span> <span class="o">:=</span> <span class="nx">exec</span><span class="p">.</span><span class="nx">LookPath</span><span class="p">(</span><span class="s">&quot;ls&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">lookErr</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">lookErr</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p><code>Exec</code> requires arguments in slice form (as
apposed to one big string). We&rsquo;ll give <code>ls</code> a few
common arguments. Note that the first argument should
be the program name.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">args</span> <span class="o">:=</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;ls&quot;</span><span class="p">,</span> <span class="s">&quot;-a&quot;</span><span class="p">,</span> <span class="s">&quot;-l&quot;</span><span class="p">,</span> <span class="s">&quot;-h&quot;</span><span class="p">}</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p><code>Exec</code> also needs a set of <a href="environment-variables">environment variables</a>
to use. Here we just provide our current
environment.</p>
</td>
<td class="code leading">
<div class="highlight"><pre> <span class="nx">env</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nx">Environ</span><span class="p">()</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Here&rsquo;s the actual <code>syscall.Exec</code> call. If this call is
successful, the execution of our process will end
here and be replaced by the <code>/bin/ls -a -l -h</code>
process. If there is an error we&rsquo;ll get a return
value.</p>
</td>
<td class="code">
<div class="highlight"><pre> <span class="nx">execErr</span> <span class="o">:=</span> <span class="nx">syscall</span><span class="p">.</span><span class="nx">Exec</span><span class="p">(</span><span class="nx">binary</span><span class="p">,</span> <span class="nx">args</span><span class="p">,</span> <span class="nx">env</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">execErr</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">execErr</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
<p>When we run our program it is replaced by <code>ls</code>.</p>
</td>
<td class="code leading">
<div class="highlight"><pre><span class="gp">$</span> go run execing-processes.go
<span class="go">total 16</span>
<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 execing-processes.go</span>
</pre></div>
</td>
</tr>
<tr>
<td class="docs">
<p>Note that Go does not offer a classic Unix <code>fork</code>
function. Usually this isn&rsquo;t an issue though, since
starting goroutines, spawning processes, and exec&rsquo;ing
processes covers most use cases for <code>fork</code>.</p>
</td>
<td class="code empty">
</td>
</tr>
</table>
<p class="next">
Next example: <a href="signals">Signals</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> | <a href="https://github.com/mmcgrana/gobyexample/blob/master/examples/execing-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 \"os\"\u000A \"os/exec\"\u000A \"syscall\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' binary, lookErr :\u003D exec.LookPath(\"ls\")\u000A if lookErr !\u003D nil {\u000A panic(lookErr)\u000A }\u000A');codeLines.push(' args :\u003D []string{\"ls\", \"-a\", \"-l\", \"-h\"}\u000A');codeLines.push(' env :\u003D os.Environ()\u000A');codeLines.push(' execErr :\u003D syscall.Exec(binary, args, env)\u000A if execErr !\u003D nil {\u000A panic(execErr)\u000A }\u000A}\u000A');codeLines.push('');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>