golang

Golang Exec

The exec package is defined under the OS package. It is simply a sub-package that allows you to execute external commands using Go.

In this guide, we will explore how we can use the exec package in to run external commands.

Importing the Exec Package

To use the exec package, we need to import it. We can do this using a simple import command as:

import "os/exec"

Once imported, you can execute commands, as we will see in this article.

Golang Execute Commands

Let us start with a basic command call to illustrate how to use the exec package. An example code is as shown below:

package main
import (
    "fmt"
    "log"
    "os/exec"
)
funcmain() {
    cmd := exec.Command("dir")
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Output:\n%s\n", string(output))
}

In the example above, we use the exec command to get the list of files and directories using the dir command.

We start by defining the command to run using the Command method. The syntax is as shown:

func Command(name string, arg ...string) *Cmd

The function takes the commands to run as a string argument. It then returns a command struct to execute the command with the provided arguments.

The next step is to run the command using the CombinedOutput method. The method syntax is as shown:

func (c *Cmd) CombinedOutput() ([]byte, error)

The method runs the command and returns the combined stdout and stderr. This returns a byte slice, which we convert into a string using the string method.

Once you run the code above, it should return the files and directories in the current working directory.

Set Current Working Directory

We can define the current working directory to on which to execute the command using the cmd.Dir variable. An example is as shown:

package main
import (
    "fmt"
    "log"
    "os/exec"
)
funcmain() {
    cmd := exec.Command("dir")
    cmd.Dir = ".."
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Output:\n%s\n", string(output))
}

Capture Stdout & StdErr Seperately.

Instead of combining Stdout and Stderr, you can capture them separately as shown in the code below:

    cmd := exec.Command("dir")
    cmd.Dir = ".."
    var stdout, stderr bytes.Buffer
    cmd.Stderr = &stderr
    cmd.Stdout = &stdout
    err := cmd.Run()
    if err != nil {
        log.Fatal(err)
    }
    output, err := string(stdout.Bytes()), string(stderr.Bytes())

Specify OS

You can also define custom commands for a different OS using the runtime.GOOS method. For example:

ifruntime.GOOS == "windows" {
cmd = exec.Command("dir")
}

Pipe Commands

You can also pipe the output of a previous command as shown in the example above:

package main
import (
    "fmt"
    "log"
    "os/exec"
)

funcmain() {
    first_cmd := `echo "Hello world" | wc -c`
    cmd := exec.Command("bash", "-c", first_cmd)
    output, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Output \n%s\n", string(output))
}

The above command should return the number of characters from the echo command.

Closing

This short guide illustrates how to get started with the exec package in Golang.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list