I have check this link about how to connect two pipe command as below code.
func main() {
c1 := exec.Command("ls")
c2 := exec.Command("wc", "-l")
c2.Stdin, _ = c1.StdoutPipe()
c2.Stdout = os.Stdout
_ = c2.Start()
_ = c1.Run()
_ = c2.Wait()
}
But now I have several command that is more than 2. the command will run as c1 | c2 | c3 | c4 | c5
, and these commands are put in a slice([](*exec.Cmd)
).
Question:
How can I loop slice and execute command as sequence and get the final result? Thanks.
You have to do exactly what you are doing currently, except that you have to do it with loops. Here is a full example which do nothing more than your own example case:
package main
import (
"os"
"os/exec"
)
func main() {
var err error // To store error during the processing. You should always check for errors and handle them. That's not an option.
var commands []*exec.Cmd // The slice that will store the commands.
// You own commands
commands = append(commands, exec.Command("ls"))
commands = append(commands, exec.Command("wc", "-l"))
// Connect each command input to the output of the previous command (starting with the second command, obviously)
for i := 1; i < len(commands); i++ {
commands[i].Stdin, err = commands[i - 1].StdoutPipe()
if err != nil {
panic(err)
}
}
commands[len(commands)-1].Stdout = os.Stdout // Last command output is connected to the standard output
// Start each command. note that the reverse order isn't mandatory, you just have to avoid runing the first command now
for i := len(commands) - 1; i > 0; i-- {
err = commands[i].Start()
if err != nil {
panic(err)
}
}
// Run the first command
commands[0].Run()
// Then wait for each subsequent command to finish
for i := 1; i < len(commands); i++ {
err = commands[i].Wait()
if err != nil {
panic(err)
}
}
}