-
-
Save masahide/9064894 to your computer and use it in GitHub Desktop.
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
package main | |
import ( | |
"bytes" | |
"exec" | |
"log" | |
"os" | |
) | |
// 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. | |
func Pipeline(cmds ...*exec.Cmd) (pipeLineOutput, collectedStandardError []byte, pipeLineError os.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 os.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 | |
} | |
func main() { | |
// Collect directories from the command-line | |
var dirs []string | |
if len(os.Args) > 1 { | |
dirs = os.Args[1:] | |
} else { | |
dirs = []string{"."} | |
} | |
// Run the command on each directory | |
for _, dir := range dirs { | |
// find $DIR -type f # Find all files | |
ls := exec.Command("find", dir, "-type", "f") | |
// | grep -v '/[._]' # Ignore hidden/temporary files | |
visible := exec.Command("egrep", "-v", `/[._]`) | |
// | sort -t. -k2 # Sort by file extension | |
sort := exec.Command("sort", "-t.", "-k2") | |
// Run the pipeline | |
output, stderr, err := Pipeline(ls, visible, sort) | |
if err != nil { | |
log.Printf("dir %q: %s", dir, err.String()) | |
} | |
// Print the stdout, if any | |
if len(output) > 0 { | |
log.Printf("%q:\n%s", dir, output) | |
} | |
// Print the stderr, if any | |
if len(stderr) > 0 { | |
log.Printf("%q: (stderr)\n%s", dir, stderr) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment