在linux中通过管道能够让一个命令的输出变为另一个命令的输入,下面是一个典型的例子:
> cat words | sort | uniq
apple
bye
hello
zebra
下面我们来用golang实现一个简单的命令:将输入都变为大写字母,效果如下:
> cat words | sort | uniq | uppercase
APPLE
BYE
HELLO
ZEBRA
我们需要实现uppercase命令,能够正确的识别出管道,本次我们命令的骨架使用Cobra。
第一步:创建命令
var rootCmd = &cobra.Command{
Use: "uppercase",
Short: "Transform the input to uppercase letters",
Long : `Simple demo of the usage of linux pipes
Transform the input (pipe of file) to uppercase letters`,
RunE: func(cmd *cobra.Command, args []string) error {
print = logNoop
if flags.verbose {
print = logOut
}
return runCommand()
},
}
采用Cobra框架,RunE是命令执行会返回err,命令的主体逻辑都在runCommand中。
第二步:判断是否是在管道:
func isInputFromPipe() bool {
fi, _ := os.Stdin.Stat()
return fi.Mode()&os.ModeCharDevice == 0
}
第三步:主体逻辑,将小写转为大写:
func toUppercase(r io.Reader, w io.Writer) error {
scanner := bufio.NewScanner(bufio.NewReader(r))
for scanner.Scan() {
_, e := fmt.Fprintln(
w, strings.ToUpper(scanner.Text()))
if e != nil {
return e
}
}
return nil
}
以上就是全部逻辑,完整的代码可以查看:
go-linux-pipes
总结
- 命令行程序可以使用Cobra
- 如何判断是否是从管道读取