Go Cheatsheet - Run External Process

·

2 min read

Run External Process

We can use os/exec module's Command function to call external program.

Use Output

proc := exec.Command("ls", "-l")
output, err := proc.Output()
if err != nil {
    log.Fatalln("Process running error", err)
}
fmt.Println(string(output))

Use Run

proc2 := exec.Command("cd", "/")
if err := proc2.Run(); err != nil {
    log.Fatalln("Process running error", err)
}
fmt.Println(proc2.ProcessState.Success()) // true or false to indicate program successfully terminated

Use Start and Wait

Start starts the specified command but does not wait for it to complete. (Run asynchronously)

proc3 := exec.Command("ls", "-l")
out := bytes.NewBuffer([]byte{})
proc3.Stdout = out
proc3.Start()
proc3.Wait()
if proc3.ProcessState.Success() {
    fmt.Print(out.String())
}

Result:

total 8
-rw-r--r--  1 johndoe  staff  1237 Apr 22 23:12 main.go

Use StdoutPipe

The code below will monitor external program's stdout, and set a running max time. When the time is up, master will keep the child program.

    proc4 := exec.Command("ping", "google.com")
    stdout, err := proc4.StdoutPipe()
    proc4.Start()
    quit := make(chan bool)
    ch := make(chan string)
    go func() {
        buf := make([]byte, 512)
        for {
            n, err := stdout.Read(buf)
            if err != nil {
                fmt.Println("Process stdout error", err)
                break
            }
            if n != 0 {
                ch <- string(buf[:n])
            }
        }
        fmt.Println("Process ended")
        close(ch)
    }()

    quit := make(chan bool)
    time.AfterFunc(5*time.Second, func() {
        quit <- true
    })

running:
    for {
        select {
        case s, ok := <-ch:
            if !ok {
                break running
            }
            fmt.Print(s)
        case <-quit:
            fmt.Println("Process running timeout")
            proc4.Process.Kill()
        }
    }

Result:

PING google.com (172.217.9.238): 56 data bytes
64 bytes from 172.217.9.238: icmp_seq=0 ttl=116 time=13.415 ms
64 bytes from 172.217.9.238: icmp_seq=1 ttl=116 time=20.761 ms
64 bytes from 172.217.9.238: icmp_seq=2 ttl=116 time=20.706 ms
64 bytes from 172.217.9.238: icmp_seq=3 ttl=116 time=21.156 ms
64 bytes from 172.217.9.238: icmp_seq=4 ttl=116 time=19.031 ms
Process running timeout
Process stdout error EOF
Process ended