在命令行中成为好公民意味着使用管道。
使用竖线|
我们可以将一个命令的输出作为另一个命令的输入来传递,并链接多个命令以提供唯一的输出。
我制作了2个使用管道作为输入的教程,建立了古柯赛和戈洛尔卡特,但是我没有详细描述从管道获取输入的过程,因此这里是有关此主题的文章。
这是一个例子:
package main
import (
“bufio”
“fmt”
“io”
“os”
)
func main() {
info, err := os.Stdin.Stat()
if err != nil {
panic(err)
}
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Mode</span>()<span style="color:#f92672">&</span><span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">ModeCharDevice</span> <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span> <span style="color:#f92672">||</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Size</span>() <span style="color:#f92672"><=</span> <span style="color:#ae81ff">0</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"The command is intended to work with pipes."</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">"Usage: fortune | gocowsay"</span>)
<span style="color:#66d9ef">return</span>
}
<span style="color:#a6e22e">reader</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">bufio</span>.<span style="color:#a6e22e">NewReader</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdin</span>)
<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">output</span> []<span style="color:#66d9ef">rune</span>
<span style="color:#66d9ef">for</span> {
<span style="color:#a6e22e">input</span>, <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">reader</span>.<span style="color:#a6e22e">ReadRune</span>()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> <span style="color:#f92672">&&</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
<span style="color:#66d9ef">break</span>
}
<span style="color:#a6e22e">output</span> = append(<span style="color:#a6e22e">output</span>, <span style="color:#a6e22e">input</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">j</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">j</span> < len(<span style="color:#a6e22e">output</span>); <span style="color:#a6e22e">j</span><span style="color:#f92672">++</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"%c"</span>, <span style="color:#a6e22e">output</span>[<span style="color:#a6e22e">j</span>])
}
}
让我们研究一下它是如何工作的。第一条有趣的线:
info, err := os.Stdin.Stat()
os.Stdin
像Stdout和Stderr一样,是开放的文件。它指向标准输入文件描述符。
Stat()
是File的方法,该方法返回一个文件信息描述文件,提供包括模式和文件大小的信息。
下一个有趣的部分是
info.Mode()&os.ModeCharDevice != 0
FileInfo.Mode()
返回uint32
将文件模式和权限确定为const的掩码(https://golang.org/pkg/os/#FileMode)。
Usign按位与并确定文件模式是否为os.ModeCharDevice。这是确保文件指向ModeCharDevice
,Unix字符设备(终端)。由于文件指向os.Stdin
,我们基本上排除了输入是管道的情况。
如果模式是不是我们通过的常数。我们也可以检查
info.Mode()&os.ModeCharDevice == os.ModeCharDevice
相同,但更具可读性。
如果这是错误的,我们将另外检查
info.Size() <= 0
与上一个检查结合使用,请确保具有输入管道,并且该管道实际上包含一些字节。
我们也可以检查
if info.Mode()&os.ModeNamedPipe != 0 {
// we have a pipe input
}
并确保输入来自管道。
接下来,程序创建一个阅读器
reader := bufio.NewReader(os.Stdin)
bufio
是一个实现缓冲I / O的程序包,基本上是包装io.Reader
和io.Writer
。
我们要求它使用默认的缓冲区大小(即4096字节)为os.Stdin提供一个缓冲的读取器。
bufio.Reader
提供了许多读取数据的方法:ReadByte
,ReadBytes
,ReadLine
,ReadRune
,ReadSlice
,ReadString
。
该示例使用ReadRune
因此可以将每个符文添加到var output []rune
切片和处理统一码字符不费吹灰之力。
阅读更多
更多教程:
- 使用NGINX反向代理服务Go服务
- 在Go中复制结构
- Go Web服务器的基础
- 在Go中对地图类型进行排序
- 简而言之去指针
- 转到标签说明
- 开始日期和时间格式
- 使用Go进行JSON处理
- 可变参数函数
- 去弦备忘单
- 转到空界面说明
- 使用VS Code和Delve调试Go
- 命名为Go返回参数
- 在Go中生成随机数和字符串
- Go项目的文件系统结构
- Go中的二进制搜索算法
- 在Go中使用命令行标志
- GOPATH解释
- 使用Go构建一个命令行应用程序:lolcat
- 使用Go构建CLI命令:Cowsay
- 在Go中使用壳管
- Go CLI教程:财富克隆
- 使用Go列出文件夹中的文件
- 使用Go从GitHub获取存储库列表
- 去,将一小段字符串附加到文件中
- 去,将字符串转换为字节片
- 使用Go可视化您本地的Git贡献
- Go CPU和内存分析入门
- 解决Go程序中的“不支持索引”错误
- 测量Go程序中的执行时间
- 使用Go构建Web爬网程序以检测重复的标题
- 最佳实践:指针还是价值接收者?
- 最佳实践:您应该使用方法还是函数?
- Go数据结构:集
- 前往地图备忘单
- 在Go中生成泛型类型的实现
- Go数据结构:字典
- Go数据结构:哈希表
- 在“通过通道”中实现事件侦听器
- Go数据结构:堆栈
- Go数据结构:队列
- Go数据结构:二进制搜索树
- Go数据结构:图形
- Go数据结构:链表
- Go数据结构的完整指南
- 比较Go值
- Go是面向对象的吗?
- 在Go中使用SQL数据库
- 在Go中使用环境变量
- 上篇教程:PostgreSQL支持的REST API
- 在Go Web服务器上启用CORS
- 在Docker容器中部署Go应用程序
- 为什么Go是作为PHP开发人员学习的功能强大的语言
- 去,删除io.Reader.ReadString换行符
- 开始,如何观看更改并重建程序
- 去算一下自约会以来的月份
- 在Go中访问HTTP POST参数