The Go exec package makes it pretty easy to run an OS command and read the output; and there are a few examples of how to pipe the output of one command into another (e.g. lsof | wc -l):
lsof := exec.Command("lsof") wc := exec.Command("wc", "-l") outPipe, err := lsof.StdoutPipe() if err != nil { return nil, err } lsof.Start() wc.Stdin = outPipe out, err := wc.Output() if err != nil { return nil, err } return out, nil
There’s a problem with this code though, the pipe will never be closed; if the caller is a long-lived process then it will leak file descriptors.
You don’t normally have to worry about this, as calling Run or Output (instead of Start) will take care of it; but we can’t use those as they’ll close the pipe too early.
The problem is easily solved, either by closing the pipe yourself:
outPipe, err := lsof.StdoutPipe() defer outPipe.Close()
or by calling Wait after the output from the second command has been received:
out, err := wc.Output() if err != nil { return nil, err } err = lsof.Wait() if err != nil { return nil, err } return out, nil