Golangはos/execパッケージを使用して外部コマンドを実行できます。
基本
処理したいコマンドをexec.Command()に渡します。
第一引数がコマンド、第二引数以降(可変長)はコマンドオプションです。
https://golang.org/pkg/os/exec/#Command
コマンドを実行する(結果を取得しない)
単に実行するだけであれば、.Run()を使います。
.Run()の場合、コマンドの実行が完了するまで待ちます。
err := exec.Command("ls", "-la").Run()
コマンドを実行して結果を取得する
実行結果も取得したい場合は.Output()を使います。
こちらも.Run()同様、コマンドの完了を待ちます。
out, err := exec.Command("ls", "-la").Output()
コマンドを実行するが、完了を待たない
完了を待たなくて良い場合は、.Start()を使います。
.Start()で開始したコマンドの終了を待ちたい時は、後述の.Wait()を使います。
err := exec.Command("nc", "-l").Start()
コマンドの完了を待つ
.Start()で開始したコマンドの終了を待つ場合、.Wait()を使います。
下記はsleep 5sを.Start()した後に.Wait()するサンプルです。
package main
import (
	"fmt"
	"os/exec"
	"time"
)
func main() {
	fmt.Println("処理開始: ", time.Now().Format("15:04:05"))
	cmd := exec.Command("sleep", "5s")
	cmd.Start()
	fmt.Println("sleep中: ", time.Now().Format("15:04:05"))
	cmd.Wait()
	fmt.Println("sleep終了: ", time.Now().Format("15:04:05"))
}
実行結果
処理開始:  19:23:16
sleep中:  19:23:16
sleep終了:  19:23:21
.Wait()で5秒待ってくれてますね。
標準入力を渡す
.StdinPipe()を使うとコマンドに標準入力を渡せます。
package main
import (
    "fmt"
    "io"
    "os/exec"
)
func main() {
    cmd := exec.Command("wc")
    stdin, _ := cmd.StdinPipe()
    io.WriteString(stdin, "hoge")
    stdin.Close()
    out, _ := cmd.Output()
    fmt.Printf("結果: %s", out)
}
実行結果
結果:        0       1       4
パイプやリダイレクトを使う
パイプやリダイレクトは直接exec.Command()に渡せないので、sh -cの引数として渡します。
cmdstr := "ip route | grep default"
out, err := exec.Command("sh", "-c", cmdstr).Output()
ただし、上記の方法だと環境変数まわりで事故る可能性があるので、安全にやりたい方はgo-pipeline使うのがおすすめです。
コマンド文字列をexec.Commandの引数として渡したい
コマンドとオプションが一緒に格納されている文字列をexec.Command()に渡したい場合、mattnさん作のgo-shellwordsを使うと便利です。
下記の関数は、コマンドとオプションが入った文字列をgo-shellwordsでパース(スライス化)してexec.Command().Run()を呼び出すサンプルです。
func runCmdStr(cmdstr string) error {
	// 文字列をコマンド、オプション単位でスライス化する
	c, err := shellwords.Parse(cmdstr)
	if err != nil {
		return err
	}
	switch len(c) {
	case 0:
		// 空の文字列が渡された場合
		return nil
	case 1:
		// コマンドのみを渡された場合
		err = exec.Command(c[0]).Run()
	default:
		// コマンド+オプションを渡された場合
		// オプションは可変長でexec.Commandに渡す
		err = exec.Command(c[0], c[1:]...).Run()
	}
	if err != nil {
		return err
	}
	return nil
}
実行している(した)コマンドのPIDを取得する
PIDは、Cmd型のProcess.Pidで参照できます。
コマンド実行前に参照するとpanic起こすので注意。
また、Process配下のメソッドでプロセスをkillしたりシグナル送ったりできます。
参考:https://golang.org/pkg/os/#Process
package main
import (
	"fmt"
	"os/exec"
)
func main() {
	cmd := exec.Command("bash")
	cmd.Start()
	fmt.Println("実行中: ", cmd.Process.Pid)
	cmd.Process.Kill()
	cmd.Wait()
	fmt.Println("Kill後: ", cmd.Process.Pid)
}
実行結果
実行中:  19558
Kill後:  19558
実行ファイルのパスを知りたい
exec.LookPathを使うとwhich的なことができます。
package main
import (
	"fmt"
	"log"
	"os/exec"
)
func main() {
	path, err := exec.LookPath("go")
	if err != nil {
		log.Fatal("not found")
	}
	fmt.Printf("go is available at %s\n", path)
}
実行結果
go is available at /usr/local/go/bin/go