Go的分页输出
我正在尝试使用$PAGER从golang打印stdout,或者手动调用或多或少的命令,以允许用户轻松地滚动浏览许多选项。如何实现这一点?您可以使用该软件包启动一个运行较少的进程或$PAGER中的任何进程,然后将字符串传输到其标准输入。以下几点对我很有用:Go的分页输出,go,stdout,pager,Go,Stdout,Pager,我正在尝试使用$PAGER从golang打印stdout,或者手动调用或多或少的命令,以允许用户轻松地滚动浏览许多选项。如何实现这一点?您可以使用该软件包启动一个运行较少的进程或$PAGER中的任何进程,然后将字符串传输到其标准输入。以下几点对我很有用: func main() { // Could read $PAGER rather than hardcoding the path. cmd := exec.Command("/usr/bin/less") // F
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)
}
}
您可以使用该包启动运行较少的进程或$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)
}
}
下面是一个有点幼稚的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)
}
}
}
下面是一个有点幼稚的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)
}
}
}
我假设您已经有了从程序打印到标准输出的输出,您希望捕获这些输出并将其发送到寻呼机,但您不想这样做 重写I/O以使用其他响应所需的其他输入流 通过将一面连接到寻呼机,另一面连接到标准输出,您可以创建一个操作系统管道,其工作原理与使用| less运行命令相同,如下所示:
// 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
}()
我假设您已经有了从程序打印到标准输出的输出,您希望捕获这些输出并将其发送到寻呼机,但您不想这样做 重写I/O以使用其他响应所需的其他输入流 通过将一面连接到寻呼机,另一面连接到标准输出,您可以创建一个操作系统管道,其工作原理与使用| less运行命令相同,如下所示:
// 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
}()
此版本为所有要分页的输出创建一个名为pager的io.Writer。如果愿意,您可以将其分配给os.Stdout,并正确关闭它,并在main返回时等待$pager
此版本为所有要分页的输出创建一个名为pager的io.Writer。如果愿意,您可以将其分配给os.Stdout,并正确关闭它,并在main返回时等待$pager
这个问题很不清楚。如果您打印到标准输出,并且用户手动调用寻呼机,那么。。。你已经实现了你想要的。我想这个问题很好地解释了我想要什么。我试图实现的是将我的go程序的标准连接到$PAGER呼叫。这个问题非常不清楚。如果您打印到标准输出,并且用户手动调用寻呼机,那么。。。你已经实现了你想要的。我想这个问题很好地解释了我想要什么。据ls I称,我试图实现的是在2012年10月前将我的go程序的stdout传输到$PAGERYears。我模模糊糊地记得,实际使用它时存在一些问题,例如,我尝试将它添加到godoc中,使其与启用寻呼机扩展的hg man一样,但我最终还是通过命令行上的一个寻呼机进行了管道传输。你可以通过w向进程写入任意代码。你是对的,根据ls I,你可以:pager:=os.ExpandEnv$pageryear2012年10月之前。我模模糊糊地记得,实际使用它时存在一些问题,例如,我尝试将它添加到godoc中,使其与启用寻呼机扩展的hg man一样,但我最终还是通过命令行上的一个寻呼机进行了管道传输。您可以通过w向进程写入任意代码。您是对的,您可以:pager:=os.ExpandEnv$PAGERah,它已关闭。关闭,我丢失了。这可以让你使用更少的导航,而不会弄乱upah,它已经过时了。我错过了。这样可以减少导航,而不会造成混乱