如何将缓冲区打印到通过分页器传输的标准输出?

huangapple go评论97阅读模式
英文:

How do I print a buffer to stdout piped through a pager?

问题

我有一个大的缓冲区(buffer []byte),我想将其打印到标准输出,但通过类似于less或more的分页器进行管道传输。有点像man命令。我不想先将缓冲区写入临时文件,也不想让用户在命令行上手动将输出导向分页器。

我可以找到如何将一个命令的输出导向另一个命令的示例,但没有关于从内部缓冲区开始的示例。

有什么想法吗?
谢谢。

英文:

I have a large buffer (buffer []byte) that I would like to print to stdout but pipe through a pager like less or more. Kind of like the man command. I don't want to write the buffer to tmp file first or make the user manually pipe the output to a pager on the command line.

I can find examples of how to pipe the output of one command to another, but nothing starting with an internal buffer.

Any ideas?
Thanks.

答案1

得分: 2

为了将输出导向到分页器,你可以像这样做:

package main

import (
	"fmt"
	"io"
	"os"
	"os/exec"
)

func main() {
	// 声明你的分页器
	cmd := exec.Command("less")
	// 创建一个管道(阻塞)
	r, stdin := io.Pipe()
	// 设置输入输出
	cmd.Stdin = r
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// 创建一个阻塞的通道,运行分页器并在完成后解除阻塞
	c := make(chan struct{})
	go func() {
		defer close(c)
		cmd.Run()
	}()

	// 将任何内容写入管道
	fmt.Fprintf(stdin, "hello world\n")

	// 关闭输入流(导致分页器退出)
	stdin.Close()

	// 等待分页器完成
	<-c
}

这段代码使用os/exec包来执行外部命令,并将输出导向到分页器(这里使用的是less命令)。它创建了一个管道来连接程序的标准输入和分页器的标准输出,然后将内容写入管道。最后,关闭输入流以使分页器退出,并等待分页器完成执行。

英文:

In order to pipe to a pager, you can do something like this:

package main

import (
        &quot;fmt&quot;
        &quot;io&quot;
        &quot;os&quot;
        &quot;os/exec&quot;
)

func main() {
        // declare your pager
        cmd := exec.Command(&quot;less&quot;)
        // create a pipe (blocking)
        r, stdin := io.Pipe()
        // Set your i/o&#39;s
        cmd.Stdin = r
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr

        // Create a blocking chan, Run the pager and unblock once it is finished
        c := make(chan struct{})
        go func() {
                defer close(c)
                cmd.Run()
        }()

        // Pass anything to your pipe
        fmt.Fprintf(stdin, &quot;hello world\n&quot;)

        // Close stdin (result in pager to exit)
        stdin.Close()

        // Wait for the pager to be finished
        &lt;-c
}

答案2

得分: 0

听起来你需要的是一个“编码器”(Encoder)。你是否在使用一个分页的包?如果是的话,你可以在该包中寻找一个编码器,如果没有提供的话,你可以自己创建一个。

下面是一个示例,展示了如何使用 JSON 编码器来实现类似于你尝试做的事情:

b := []byte(`{ ... some json object ... }`)
json_encoder := json.NewEncoder(os.Stdout)
json_encoder.Encode(b)

在这个示例中,JSON 编码器接受 []byte 类型的数据,并将其编码成 JSON 文档,并写入提供的 io.Writer。如果你正在使用一个包,但它没有提供编码器,你可以通过查看 JSON 编码器 的源代码来获取创建自己编码器的思路。

英文:

Sounds like what you need is an Encoder. Are you using a package for the pager? If so you might want to look for an Encoder in the package, or create your own if one isn't provided.

Here is an example of how you could use a JSON Encoder to achieve something similar to what you're trying to do:

b := []byte(`{ ... some json object ... }`)
json_encoder := json.NewEncoder(os.Stdout)
json_encoder.Encode(b)

In this example, the JSON encoder accepts the []byte and does all the work to encode it into a JSON document and write to the provided io.writer. If you're using a package and it doesn't provide an encoder, you can get ideas on how to write one by looking into the JSON Encoder source code to create your own.

huangapple
  • 本文由 发表于 2014年2月13日 04:16:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/21738674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定