Go读取Linux命令行管道参数

寒江蓑笠翁大约 3 分钟技术日志go命令行go

Go读取Linux命令行管道参数


在用go编写命令行程序的时候,参数有三个来源

  1. 命令行参数
  2. 命令行标志
  3. 管道

Linux管道是一个很常见的用法,用于将上一个命令的结果作为下一个命令的参数

$ cat hello.txt | grep hello

但并不是所有命令行程序都支持管道参数,比如echo就不支持,这种情况我们一般会用xargs来转化下。

$ cat hello.txt | xargs echo

它会读取管道参数然后作为标准命令行参数传递给下一个命令,不过它有可能会破坏源文件的内容,所以我们还是自身支持管道更好一些。

在使用管道时,实际上是将结果写入了标准输入stdin中,对于我们而言,就只需要从标准输入中读取就行了。很容易就能想到该怎么写

args, _ := io.ReadAll(os.Stdin)

可如果只是直接从标准输入读取,如果在使用命令的时候没有使用管道,那么这行代码就会一直阻塞下去。所以我们得首先判断是否是管道模式,再去读取管道参数,所以应该这样写

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {
	stat, _ := os.Stdin.Stat()
	if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
		bytes, _ := io.ReadAll(os.Stdin)
		fmt.Println(string(bytes))
		return
	}
	fmt.Println("do nothing")
}

看看使用情况

$ cat main.go | ./main.exe
package main

import (
        "fmt"
        "io"
        "os"
)

func main() {
        stat, _ := os.Stdin.Stat()
        if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
                bytes, _ := io.ReadAll(os.Stdin)
                fmt.Println(string(bytes))
                return
        }
        fmt.Println("do nothing")
}

不使用管道

$ ./main.exe
do nothing

这样一来,就可以区分使用管道和不使用管道的情况了,在不使用管道的情况下就可以从标准命令行参数里面去读取。

上次编辑于:
贡献者: 246859