[Golang] Check If A Program (Command) Exists
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:
| [1] | 
| [2] | shell - Check if a program exists from a Bash script - Stack Overflow | 
| [3] | 
| [4] | go - How to execute a linux built in command in golang - Stack Overflow | 
| [5] | 
| [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 |