loading...

Quick Notes for Go os/exec

tobychui profile image Toby Chui ・2 min read

Golang's os/exec package is tricky to use. For beginners, you might have a lot of questions like

  • How to use os/exec with multiple parameters?
  • Why the cwd of the exec call is not what I have assigned?
  • How to pass piped command into the exec function call?

In this notes, I will show some quick examples on how to use os/exec with some conditions that is kind of common if you are working on a project that requires interaction to other software binary / system commands.

⌨ A very basic os/exec function call

Lets start from here, this is a basic exec function call and the results are returned in "out" as []byte

func main() {
    cmd := exec.Command("ls", "-lah")
    out, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatalf("cmd.Run() failed with %s\n", err)
    }
    fmt.Printf("combined out:\n%s\n", string(out))
}
Enter fullscreen mode Exit fullscreen mode

🌲 os/exec function call with extra Environment variable

cmd := exec.Command("programToExecute")
additionalEnv := "FOO=bar"
newEnv := append(os.Environ(), additionalEnv)
cmd.Env = newEnv
out, err := cmd.CombinedOutput()
if err != nil {
    log.Fatalf("cmd.Run() failed with %s\n", err)
}
fmt.Printf("%s", out)
Enter fullscreen mode Exit fullscreen mode

📁 Set the cwd of the execution path

cmd:= exec.Command("git", "log")
cmd.Dir = "your/intended/working/directory"
out, err := cmd.Output()
Enter fullscreen mode Exit fullscreen mode

Notes: If you are calling a binary instead of a variable / program inside the ENV variable (or %PATH% in Window's case), use the absolute path of the binary. For example

abspath, _ := filepath.Abs("./mybinary")
cmd:= exec.Command(abspath, "log")
cmd.Dir = "your/intended/working/directory"
out, err := cmd.Output()
Enter fullscreen mode Exit fullscreen mode

⌨️ Use os/exec with Linux pipe / bash commands

rcmd := `iw dev | awk '$1=="Interface"{print $2}'`
cmd := exec.Command("bash", "-c", rcmd)
out, err := cmd.CombinedOutput()
if err != nil {
    log.Println(err.Error())
}
log.Println(string(out))
Enter fullscreen mode Exit fullscreen mode

🖥️ Use os/exec with Windows Batch commands

cmd := exec.Command("cmd", "/c", "ffmpeg -i myfile.mp4 myfile.mp3 && del myfile.mp4")
out, err := cmd.CombinedOutput()
if err != nil {
    log.Println(err.Error())
}
log.Println(string(out))
Enter fullscreen mode Exit fullscreen mode

📑 Use string slice in os/exec function call

args := []string{"hello", "world"}
cmd := exec.Command("echo", args...)
out, err := cmd.Output()
if err != nil {
    fmt.Println(err)
}
fmt.Println(string(out))
Enter fullscreen mode Exit fullscreen mode

🍆 Solving localization problem in Windows CMD for os/exec

This is suitable for developers that is using a non-Unicode supported version of Windows with default codepage of cmd localized in not English language.

cmd := exec.Command("cmd", "/c", "chcp 65001 && netsh WLAN show drivers")
out, err := cmd.CombinedOutput()
if err != nil {
    log.Println(err.Error())
}
log.Println(string(out))
Enter fullscreen mode Exit fullscreen mode

Notes: Remember to remove the first line of the output which should be a confirmation of successfully changed codepage using chcp command

If you find this useful, feel free to share or bookmark this article 😉

Discussion

pic
Editor guide
Collapse
shostarsson profile image
Rémi Lavedrine

Great one.
I used it a lot in my app and used the basics version of it.
It is great to have a memo about all the methods I can use in the future. :-)

Thanks for that article. 👍