gpt4 book ai didi

go - 通过 SSH 流式传输 Stdout 和 Stderr,操作流然后打印到本地 Stdout 和 Stderr

转载 作者:IT王子 更新时间:2023-10-29 02:07:57 31 4
gpt4 key购买 nike

我在远程机器上通过 SSH 执行一系列操作,我正在传输它的标准输出和标准错误,然后由写入器使用它,写入本地标准输出和标准错误,以及字节缓冲区。

就在编写器使用它之前,我想对其执行一系列字符串操作,然后写入我的屏幕和缓冲区。到目前为止,一切都很好而且很花哨。

我的问题是现在它不再是流,它挂起然后将整个 glob 输出为一个 block 。我希望它是实时的,所以我在我的 go 例程中加入了 channel ,但没有任何改进。以下是我的函数,如果您能找出原因或实现此目的的更好方法,请告诉我。

//发送

func handleStdStream(filters []string, replaceFilters map[string]string, pipe io.Reader, readers chan io.Reader) {
if filters != nil {
// filters exist
// read first 8 bytes
res := readPipe(8, pipe)

// get each line from the resulting streamed output
for _, str := range strings.Split(res, "\n") {
if str != "" {
out := lineFilterAndReplace(str, filters, replaceFilters)

// instantiate an io.Reader obj from the given string
outReader := strings.NewReader(out)

readers <- outReader
}
}
} else {
// filters dont exist
if len(replaceFilters) > 0 {
res := readPipe(8, pipe)

for _, str := range strings.Split(res, "\n") {
if str != "" {
out := lineReplace(str, replaceFilters)

// instantiate an io.Reader obj from the given string
outReader := strings.NewReader(out)

readers <- outReader
}
}
} else {
readers <- pipe
}
}
}

//接收

    outReaders := make(chan io.Reader)

go handleStdStream(outFilters, replaceFilters, stdoutIn, outReaders)

go func() {
for {
pipe := <-outReaders

_, errStdout = io.Copy(outWriter, pipe)
}

// _, errStdout = io.Copy(outWriter, stdoutIn)
}()

最佳答案

我认为您不需要 channel 或 goroutine 来完成此操作。 WriterReader 接口(interface)已经在流式传输;您不断地从 Reader 读取字节,直到遇到 EOF 或错误,然后不断地将字节传递给 Writer,直到完成或出现错误。就其本身而言,处理流不需要任何并发性,因此在单个 goroutine 中按顺序执行此操作非常合适。

您不应该忽略错误返回。如果函数或方法返回错误值,则需要对其进行检查。在 I/O 的情况下,您通常需要在 Reader 返回错误时停止读取,并且您通常需要在返回错误时停止写入 Writer错误。对于 Reader,您还必须检查特殊的“错误”值 io.EOF

我认为使用 bufio 包中的 Scanner 比尝试自己进行缓冲/拆分要好。默认情况下,Scanner 在换行符上拆分输入(Unix 风格的 LF 或 DOS 风格的 CRLF)。如果您仅通过 ScannerReader 交互,它也无需检查 io.EOF

考虑以下版本的handleStdStream:

func handleStdStream(filters []string, replaceFilters map[string]string, pipe io.Reader, w io.Writer) error {
scanner := bufio.NewScanner(pipe)
for scanner.Scan() {
str := scanner.Text()
if str == "" {
continue
}
out := ""
if len(filters) != 0 {
out = lineFilterAndReplace(str, filters, replaceFilters)
} else {
out = lineReplace(str, replaceFilters)
}
if _, err := w.Write([]byte(out)); err != nil {
return err
}
}
if err := scanner.Err(); err != nil {
return err
}
return nil
}

你会像这样使用它:

err := handleStdStream(filters, replaceFilters, pipe, outWriter)
if err != nil {
// do something, like printing the error to a log or stderr
}

关于go - 通过 SSH 流式传输 Stdout 和 Stderr,操作流然后打印到本地 Stdout 和 Stderr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54337616/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com