Replacing Go Process with exec

GolangGolangBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

This lab focuses on replacing the current Go process with another process using Go's implementation of the classic exec function.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("`Go`")) -.-> go/NetworkingGroup(["`Networking`"]) go/NetworkingGroup -.-> go/processes("`Processes`") subgraph Lab Skills go/processes -.-> lab-15473{{"`Replacing Go Process with exec`"}} end

Execing Processes

The problem is to replace the current Go process with another process, such as a non-Go process.

  • Go programming language
  • Basic knowledge of Go's exec function
  • Familiarity with environment variables
## When we run our program it is replaced by `ls`.
$ go run execing-processes.go
total 16
drwxr-xr-x 4 mark 136B Oct 3 16:29 .
drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
-rw-r--r-- 1 mark 1.3K Oct 3 16:28 execing-processes.go

## Note that Go does not offer a classic Unix `fork`
## function. Usually this isn't an issue though, since
## starting goroutines, spawning processes, and exec'ing
## processes covers most use cases for `fork`.

There is the full code below:

// In the previous example we looked at
// [spawning external processes](spawning-processes). 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'll use Go's
// implementation of the classic
// <a href="https://en.wikipedia.org/wiki/Exec_(operating_system)"><code>exec</code></a>
// function.

package main

import (
	"os"
	"os/exec"
	"syscall"
)

func main() {

	// For our example we'll exec `ls`. Go requires an
	// absolute path to the binary we want to execute, so
	// we'll use `exec.LookPath` to find it (probably
	// `/bin/ls`).
	binary, lookErr := exec.LookPath("ls")
	if lookErr != nil {
		panic(lookErr)
	}

	// `Exec` requires arguments in slice form (as
	// opposed to one big string). We'll give `ls` a few
	// common arguments. Note that the first argument should
	// be the program name.
	args := []string{"ls", "-a", "-l", "-h"}

	// `Exec` also needs a set of [environment variables](environment-variables)
	// to use. Here we just provide our current
	// environment.
	env := os.Environ()

	// Here's the actual `syscall.Exec` call. If this call is
	// successful, the execution of our process will end
	// here and be replaced by the `/bin/ls -a -l -h`
	// process. If there is an error we'll get a return
	// value.
	execErr := syscall.Exec(binary, args, env)
	if execErr != nil {
		panic(execErr)
	}
}

Summary

In this lab, we learned how to replace the current Go process with another process using Go's implementation of the classic exec function. This can be useful when we need to execute a non-Go process from within a Go program.

Other Golang Tutorials you may like