马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
背景
- golang可以获取命令执行的输出结果,但要执行完才能够获取。
- 如果执行的命令是ssh,我们要实时获取,并执行相应的操作呢?
示例
- func main() {
- user := "root"
- host := "172.16.116.133"
- //获取执行命令
- cmd := exec.Command("ssh", fmt.Sprintf("%s@%s", user, host))
- cmd.Stdin = os.Stdin
- var wg sync.WaitGroup
- wg.Add(2)
- //捕获标准输出
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- fmt.Println("ERROR:", err)
- os.Exit(1)
- }
- readout := bufio.NewReader(stdout)
- go func() {
- defer wg.Done()
- GetOutput(readout)
- }()
- //捕获标准错误
- stderr, err := cmd.StderrPipe()
- if err != nil {
- fmt.Println("ERROR:", err)
- os.Exit(1)
- }
- readerr := bufio.NewReader(stderr)
- go func() {
- defer wg.Done()
- GetOutput(readerr)
- }()
- //执行命令
- cmd.Run()
- wg.Wait()
- return
- }
- func GetOutput(reader *bufio.Reader) {
- var sumOutput string //统计屏幕的全部输出内容
- outputBytes := make([]byte, 200)
- for {
- n, err := reader.Read(outputBytes) //获取屏幕的实时输出(并不是按照回车分割,所以要结合sumOutput)
- if err != nil {
- if err == io.EOF {
- break
- }
- fmt.Println(err)
- sumOutput += err.Error()
- }
- output := string(outputBytes[:n])
- fmt.Print(output) //输出屏幕内容
- sumOutput += output
- }
- return
- }
复制代码 应用场景
ssh是交互式命令,本示例实现了实时获取输出结果,并判断输出结果中有没有报错,报错则重试(再次登陆)。
场景:本Demo只是把"错误"二字视为异常,然后重试,实际上比这复杂的多,比如ssh连接超时重试等,这个逻辑请自行补充。
[code]package mainimport ( "bufio" "fmt" "io" "os" "os/exec" "strings" "sync" "time")func main(){ retryTimes := 3 var retryInterval time.Duration = 3 user := "root" host := "172.16.116.133" //部分场景下重试登录 shouldRetry := true for i:=1;i |