[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 |