简体   繁体   中英

Trying to parse a stdout on command line with Golang

I'm practicing to use GoLang to pass arguements to the command line, and being able to parse information from the results that are passed out. For example, I have code that is designed to execute a command, and display what will display anyway if the command was entered through cmd anyway.

package main

import (
    "bytes"
    "fmt"
    "os"
    "os/exec"
    "strings"
)

func main() {
    cmd = exec.Command("ping", "8.8.8.8")
    cmdOutput = &bytes.Buffer{}
    cmd.Stdout = cmdOutput
    printCommand(cmd)
    err = cmd.Run()
    printError(err)
    printOutput(cmdOutput.Bytes())
}

func printCommand(cmd *exec.Cmd) {
    fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " "))
}

func printError(err error) {
    if err != nil {
        os.Stderr.WriteString(fmt.Sprintf("==> Error: %s\n", err.Error()))
    }
}

func printOutput(outs []byte) {
    if len(outs) > 0 {
        fmt.Printf("==> Output: %s\n", string(outs))
    }
}

Considering the output would be:

==> Executing: ping 8.8.8.8
==> Output:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=13ms TTL=56
Reply from 8.8.8.8: bytes=32 time=13ms TTL=56
Reply from 8.8.8.8: bytes=32 time=14ms TTL=56
Reply from 8.8.8.8: bytes=32 time=11ms TTL=56

Ping statistics for 8.8.8.8:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% lo
Approximate round trip times in milli-seconds:
    Minimum = 11ms, Maximum = 14ms, Average = 12ms

My question is: If I wanted to parse the Average response time, so I can assign that to a variable so I can display that when I want to, how can I parse that?

You can use regexp . For instance something like:

package main

import (
        "bytes"
        "fmt"
        "os"
        "os/exec"
        "regexp"
        "strings"
        "time"
)

type Ping struct {
        average time.Duration
}

func main() {
        cmd := exec.Command("ping", "8.8.8.8")
        // Linux version
        //cmd := exec.Command("ping", "-c 4", "8.8.8.8")
        cmdOutput := &bytes.Buffer{}
        cmd.Stdout = cmdOutput
        printCommand(cmd)
        err := cmd.Run()
        printError(err)
        output := cmdOutput.Bytes()
        printOutput(output)
        ping := Ping{}
        parseOutput(output, &ping)

        fmt.Println(ping)
}

func printCommand(cmd *exec.Cmd) {
        fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " "))
}

func printError(err error) {
        if err != nil {
                os.Stderr.WriteString(fmt.Sprintf("==> Error: %s\n", err.Error()))
        }
}

func printOutput(outs []byte) {
        if len(outs) > 0 {
                fmt.Printf("==> Output: %s\n", string(outs))
        }
}

func parseOutput(outs []byte, ping *Ping) {
        var average = regexp.MustCompile(`Average = (\d+ms)`)
        result := average.FindStringSubmatch(string(outs))

        if len(result) > 0 {
                ping.average, _ = time.ParseDuration(result[1])
        }
        // Linux version
        /*var average = regexp.MustCompile(`min\/avg\/max\/mdev = (0\.\d+)\/(0\.\d+)\/(0\.\d+)\/(0\.\d+) ms`)
        result := average.FindAllStringSubmatch(string(outs), -1)

        if len(result) > 0 {
                ping.average, _ = time.ParseDuration(result[0][2] + "ms")
        }*/
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM