如何使用Go捕获终端管道输入并按规则生成对应输出
可行性结论
这个需求完全可以用Go实现,标准库就提供了所需的全部能力,无需引入第三方依赖。
核心实现思路
- 首先判断程序是否接收到管道输入:通过
os.Stdin.Stat()获取标准输入的文件状态,判断Mode() & os.ModeCharDevice是否为0,结果为0就说明是管道输入,而非终端直接输入。 - 逐行读取标准输入内容:用
bufio.NewScanner(os.Stdin)创建扫描器,循环调用Scan()方法逐行读取输入内容,自动适配单行、多行输入场景。 - 加工输出:每读取一行就拼接
hi前缀后打印即可,同时兼容echo的单行输入和cat文件的多行输入需求。
最简可运行示例代码
package main import ( "bufio" "fmt" "os" ) func main() { // 检查标准输入状态 stat, err := os.Stdin.Stat() if err != nil { fmt.Fprintf(os.Stderr, "failed to get stdin stat: %v\n", err) os.Exit(1) } // 无管道输入时提示用法 if stat.Mode()&os.ModeCharDevice != 0 { fmt.Fprintln(os.Stderr, "usage: command | goprogram") os.Exit(1) } // 逐行扫描并处理输入 scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() fmt.Printf("hi %s\n", line) } // 处理扫描过程中可能出现的错误 if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "failed to read input: %v\n", err) os.Exit(1) } }
编译测试方法
- 执行
go build -o goprogram main.go编译生成二进制文件 - 测试单行输入:执行
echo "john" | ./goprogram,输出结果为hi john - 提前创建包含
doe、james、chris三行内容的list_name.txt,执行cat list_name.txt | ./goprogram,即可得到预期的多行输出结果。
内容的提问来源于stack exchange,提问作者Budi Subakti
相关产品推荐
相关产品推荐

