3

[Golang] Check If A Program (Command) Exists

 2 years ago
source link: https://siongui.github.io/2018/03/16/go-check-if-command-exists/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[Golang] Check If A Program (Command) Exists

March 16, 2018

Check if a program (or command), such as wget or ffmpeg, is available in Go.

This looks like a easy task. I made some Google searches and found [2] you can check if a command exists in shell as follows:

$ command -v <the_command>

Now we use standard os.exec package to run the command for us:

import (
      "os/exec"
)

func isCommandAvailable(name string) bool {
      cmd := exec.Command("command", "-v", name)
      if err := cmd.Run(); err != nil {
              return false
      }
      return true
}

Looks very easy. To be more confident, we write a test to see if it works:

import (
      "testing"
)

func TestIsCommandAvailable(t *testing.T) {
      if isCommandAvailable("ls") == false {
              t.Error("ls command does not exist!")
      }
      if isCommandAvailable("ls111") == true {
              t.Error("ls111 command should not exist!")
      }
}

And the test failed!!!

=== RUN   TestIsCommandAvailable
--- FAIL: TestIsCommandAvailable (0.00s)
      util_test.go:9: ls command does not exist!

I print the error message and got:

exec: "command": executable file not found in $PATH

This is really strange, and I googled again and found [4] that you cannot run built-in command directly via exec.Command, so the following way of running built-in command will not work:

cmd := exec.Command("command", "-v", name)

Instead, you should run the built-in command as follows:

cmd := exec.Command("/bin/sh", "-c", "command -v "+name)

And finally it works as expected and the test passed! The correct way to check if a program exists in Go is:

import (
      "os/exec"
)

func isCommandAvailable(name string) bool {
      cmd := exec.Command("/bin/sh", "-c", "command -v "+name)
      if err := cmd.Run(); err != nil {
              return false
      }
      return true
}

Tested on: Ubuntu 17.10, Go 1.10


References:

[6]Help! os/exec Output() on Non-English Windows cmd! : golang[7]A netstat implementation written in Go : golang[8]Shell scripter here, I can't get Go to click : golang


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK