forked from appleboy/docker-backup-database
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Bo-Yi Wu <[email protected]>
- Loading branch information
Showing
3 changed files
with
64 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package helper | ||
|
||
import ( | ||
"bytes" | ||
"os/exec" | ||
) | ||
|
||
// Pipeline strings together the given exec.Cmd commands in a similar fashion | ||
// to the Unix pipeline. Each command's standard output is connected to the | ||
// standard input of the next command, and the output of the final command in | ||
// the pipeline is returned, along with the collected standard error of all | ||
// commands and the first error found (if any). | ||
// | ||
// To provide input to the pipeline, assign an io.Reader to the first's Stdin. | ||
// ref: https://gist.github.com/kylelemons/1525278 | ||
func Pipeline(cmds ...*exec.Cmd) (pipeLineOutput, collectedStandardError []byte, pipeLineError error) { | ||
// Require at least one command | ||
if len(cmds) < 1 { | ||
return nil, nil, nil | ||
} | ||
|
||
// Collect the output from the command(s) | ||
var output bytes.Buffer | ||
var stderr bytes.Buffer | ||
|
||
last := len(cmds) - 1 | ||
for i, cmd := range cmds[:last] { | ||
var err error | ||
// Connect each command's stdin to the previous command's stdout | ||
if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil { | ||
return nil, nil, err | ||
} | ||
// Connect each command's stderr to a buffer | ||
cmd.Stderr = &stderr | ||
} | ||
|
||
// Connect the output and error for the last command | ||
cmds[last].Stdout, cmds[last].Stderr = &output, &stderr | ||
|
||
// Start each command | ||
for _, cmd := range cmds { | ||
if err := cmd.Start(); err != nil { | ||
return output.Bytes(), stderr.Bytes(), err | ||
} | ||
} | ||
|
||
// Wait for each command to complete | ||
for _, cmd := range cmds { | ||
if err := cmd.Wait(); err != nil { | ||
return output.Bytes(), stderr.Bytes(), err | ||
} | ||
} | ||
|
||
// Return the pipeline output and the collected standard error | ||
return output.Bytes(), stderr.Bytes(), nil | ||
} |