我正在尝试使用$PAGER
从golang打印到stdout,或者手动调用more
或less
以允许用户轻松滚动浏览很多选项。我怎样才能做到这一点?
答案 0 :(得分:2)
您可以使用os/exec包启动运行less
(或$PAGER
中的任何内容)的进程,然后将字符串传递给其标准输入。以下对我有用:
func main() {
// Could read $PAGER rather than hardcoding the path.
cmd := exec.Command("/usr/bin/less")
// Feed it with the string you want to display.
cmd.Stdin = strings.NewReader("The text you want to show.")
// This is crucial - otherwise it will write to a null device.
cmd.Stdout = os.Stdout
// Fork off a process and wait for it to terminate.
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
答案 1 :(得分:2)
我假设您已经从您的程序打印到stdout的输出,您想要捕获并发送到您的寻呼机,您不希望 重写I / O以使用其他响应所需的其他输入流。
您可以创建一个os.Pipe,其工作方式与运行带有“| less”的命令相同,方法是将一侧连接到寻呼机,另一侧连接到stdout,如下所示:
// Create a pipe for a pager to use
r, w, err := os.Pipe()
if err != nil {
panic("You probably want to fail more gracefully than this")
}
// Capture STDOUT for the Pager. Keep the old
// value so we can restore it later.
stdout := os.Stdout
os.Stdout = w
// Create the pager process to execute and attach
// the appropriate I/O streams.
pager := exec.Command("less")
pager.Stdin = r
pager.Stdout = stdout // the pager uses the original stdout, not the pipe
pager.Stderr = os.Stderr
// Defer a function that closes the pipe and invokes
// the pager, then restores os.Stdout after this function
// returns and we've finished capturing output.
//
// Note that it's very important that the pipe is closed,
// so that EOF is sent to the pager, otherwise weird things
// will happen.
defer func() {
// Close the pipe
w.Close()
// Run the pager
if err := pager.Run(); err != nil {
fmt.Fprintln(os.Stderr, err)
}
// restore stdout
os.Stdout = stdout
}()
答案 2 :(得分:1)
这是一个有点天真的 cat 示例,在设置时会使用$PAGER
。
package main
import (
"io"
"log"
"os"
"os/exec"
)
func main() {
var out io.WriteCloser
var cmd *exec.Cmd
if len(os.Args) != 2 {
log.Fatal("Wrong number of args: gcat <file>")
}
fileName := os.Args[1]
file, err := os.Open(fileName)
if err != nil {
log.Fatal("Error opening file: ", err)
}
pager := os.Getenv("PAGER")
if pager != "" {
cmd = exec.Command(pager)
var err error
out, err = cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
cmd.Stdout = os.Stdout
if err := cmd.Start(); err != nil {
log.Fatal("Unable to start $PAGER: ", err)
}
} else {
out = os.Stdout
}
_, err = io.Copy(out, file)
if err != nil {
log.Fatal(err)
}
file.Close()
out.Close()
if cmd != nil {
if err := cmd.Wait(); err != nil {
log.Fatal("Error waiting for cmd: ", err)
}
}
}
答案 3 :(得分:0)
此版本为您要分页的所有输出创建一个名为io.Writer
的{{1}}(如果愿意,可以将其分配给pager
),并正确关闭它并等待{ os.Stdout
返回时为{1}}。
$PAGER