乘着打盹的时间看了一眼前两天写的日期转换的开源工具: ts。发现管道 pipeline
的功能点能够放大一下, 就此记录一下以备未来只需。git
但凡在类 Unix 系统上敲过命令的人,大多使用过管道功能. 所谓管道,就是将A程序的标准输出做为B程序的标准输入。而在类 Unix 系统只须要使用 |
符号,链接 A 和 B 程序便可, 即 A | B
。经过屡次管道链接,就能够实现很是强大的功能。因此在类 Unix 系统上开发命令行程序有个著名的原则: KISS
,即 Keep It Simple Stupid。github
画了张简单的图:工具
在 Go 程序中实现管道功能及其简单,直接上码:post
//先取程序的标准输入属性信息
info, err := os.Stdin.Stat()
if err != nil {
return errors.Annotate(err, "stdin stat failed")
}
// 判断标准输入设备属性 os.ModeCharDevice 是否设置
// 同时判断是否有数据输入
if (info.Mode()&os.ModeCharDevice) == os.ModeCharDevice &&
info.Size() > 0 {
bytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
return errors.Annotate(err, "stdin read failed")
}
//TODO...
}
复制代码
属性 os.ModeCharDevice
的意思是标准输入的设备类型是Unix字节流设备(Unix character device)即终端(terminal)输入。该方式判断有一个注意点:spa
须要判断
info.Size()
, 即标准输入是有数据输入的。若是终端没有输入的话,程序会在ioutil.ReadAll
处阻塞。命令行
因此使用这种方式须要了解不一样条件设置的用途,请结合实际开发需求。除了这个方式之外,还有另外更加简单的实现方法:code
// 直接判断 标准输入属性是否设置 os.ModeNamedPipe 便可
if (info.Mode()&os.ModeNamedPipe) == os.ModeNamedPipe {
//TODO...
}
复制代码
标准输入只有在存在输入的时候,才会设置os.ModeNamedPipe
属性。相比较第一种方式,这种方式代码更加简单。只是命名管道(NamedPipe)又来了一个新概念,增长了理解的难度。引入一个 Linux 命令mkfifo
,这个命令就是建立命名管道用的。至于为何这里程序的os.Stdin
属性会是os.ModeNamedPipe
,我这先偷个懒了。cdn
更多 Go 相关文章:blog