分享
  1. 首页
  2. 文章

一分钟学会在 Go 程序中实现管道 pipeline 功能

JayL · · 2072 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

乘着打盹的时间看了一眼前两天写的日期转换的开源工具: ts。发现管道 pipeline 的功能点可以放大一下, 就此记录一下以备将来只需。

管道是什么

但凡在类 Unix 系统上敲过命令的人,大多使用过管道功能. 所谓管道,就是将A程序的标准输出作为B程序的标准输入。而在类 Unix 系统只需要使用 | 符号,连接 A 和 B 程序即可, 即 A | B。通过多次管道连接,就可以实现非常强大的功能。所以在类 Unix 系统上开发命令行程序有个著名的原则: KISS,即 Keep It Simple Stupid。

画了张简单的图:

Go 程序

在 Go 程序中实现管道功能及其简单,直接上码:

 //先取程序的标准输入属性信息
 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)输入。该方式判断有一个注意点:

需要判断 info.Size(), 即标准输入是有数据输入的。如果终端没有输入的话,程序会在 ioutil.ReadAll 处阻塞。

所以使用这种方式需要了解不同条件设置的用途,请结合实际开发需求。除了这个方式以外,还有另外更加简单的实现方法:

 // 直接判断 标准输入属性是否设置 os.ModeNamedPipe 即可
 if (info.Mode()&os.ModeNamedPipe) == os.ModeNamedPipe {
 //TODO...
 }
复制代码

标准输入只有在存在输入的时候,才会设置os.ModeNamedPipe属性。相比较第一种方式,这种方式代码更加简单。只是命名管道(NamedPipe)又来了一个新概念,增加了理解的难度。引入一个 Linux 命令mkfifo,这个命令就是创建命名管道用的。至于为什么这里程序的os.Stdin属性会是os.ModeNamedPipe,我这先偷个懒了。

更多 Go 相关文章:


有疑问加站长微信联系(非本文作者)

本文来自:掘金

感谢作者:JayL

查看原文:一分钟学会在 Go 程序中实现管道 pipeline 功能

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2072 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏