通常在啟動項目服務程序的時候,需要判斷該服務是否已經被啟動,一般的做法有兩種,其一是每次啟動后將pid寫入文件中,啟動的時候讀取這個文件,如果里面有數值,就表示服務已啟動;另一種是通過shell命令查找:
ps -ef | grep XXX | grep -v grep | awk '{print $2}'
很多語言都可以直接執行這行命令;偏偏go語言不行,因此,我們可以利用go中提供的一些方法實現它(不說了,直接上代碼):
func Pipeline(cmds ...*exec.Cmd) (pipeLineOutput, collectedStandardError []byte, pipeLineError error) { if len(cmds) < 1 { return nil, nil, nil } var output bytes.Buffer var stderr bytes.Buffer last := len(cmds) - 1 for i, cmd := range cmds[:last] { var err error if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil { return nil, nil, err } cmd.Stderr = &stderr } cmds[last].Stdout, cmds[last].Stderr = &output, &stderr for _, cmd := range cmds { if err := cmd.Start(); err != nil { return output.Bytes(), stderr.Bytes(), err } } for _, cmd := range cmds { if err := cmd.Wait(); err != nil { return output.Bytes(), stderr.Bytes(), err } } return output.Bytes(), stderr.Bytes(), nil } func ExecPipeLine(cmds ...*exec.Cmd) (string, error) { output, stderr, err := Pipeline(cmds...) if err != nil { return "", err } if len(output) > 0 { return string(output), nil } if len(stderr) > 0 { return string(stderr), nil } return "", errors.New("no returns") }
接着寫一個例子測試:
func main() { cmds := []*exec.Cmd{ exec.Command("ps", "-ef"), exec.Command("grep", "redis"), exec.Command("grep", "-v", "grep"), exec.Command("awk", "{print $2}"), } string, _ := pipeutil.ExecPipeLine() fmt.Printf("pids: %v", string) }
Bingo!切記,最后一行 awk的參數不能有單引號(‘’)(當時被坑慘了。。。)