Go Proxy exec.Cmd Stdout/Stderr而不丢失TTY

Go Proxy exec.Cmd Stdout/Stderr而不丢失TTY,go,colors,stdout,stderr,tty,Go,Colors,Stdout,Stderr,Tty,我有以下代码,它执行任意shell命令并将stdout和stderr管道传输到终端: c := exec.Command("/bin/sh", "-c", cmd) c.Stdin = os.Stdin c.Stdout = os.Stdout c.Stderr = os.Stderr 但是,我需要在打印输出之前对其进行处理,因此我使用代理io.Writer接口对其进行了包装: type ProxyWriter struct { file *os.File } func NewP

我有以下代码,它执行任意shell命令并将
stdout
stderr
管道传输到终端:

c := exec.Command("/bin/sh", "-c", cmd)
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
但是,我需要在打印输出之前对其进行处理,因此我使用代理io.Writer接口对其进行了包装:

type ProxyWriter struct {
    file   *os.File
}

func NewProxyWriter(file *os.File) *ProxyWriter {
    return &ProxyWriter{
        file: file,
    }
}

func (w *ProxyWriter) Write(p []byte) (int, error) {
    // ... do something with bytes first
    fmt.Fprintf(w.file, "%s", string(p))
    return len(p), nil
}
原来的代码是:

c := exec.Command("/bin/sh", "-c", cmd)
c.Stdin = os.Stdin
c.Stdout = NewProxyWriter(os.Stdout)
c.Stderr = NewProxyWriter(os.Stderr)
然而,这在很大程度上是有效的,
stdout
stderr
似乎不再符合TTY的资格。任何以前设置样式或着色的输出都不再设置样式或着色

我已经确认,这不是我的
ProxyWriter
通过将命令设置为以下命令(正确输出彩色文本)而简单地弄乱格式的问题

c := exec.Command("echo", "\033[0;31mTEST\033[0m")
更明确的测试是:

c := exec.Command("/bin/sh", "-c", "if [ -t 1 ] ; then echo \"terminal\"; else echo \"not a terminal\"; fi")
哪些产出:

not a terminal
是否可以在不丢失TTY状态的情况下包装命令stdout/stderr?

替换

func (w *ProxyWriter) Write(p []byte) (int, error) {
    // ... do something with bytes first
    fmt.Fprintf(w.file, "%s", string(p))
    return len(p), nil
}

fmt.Fprintf
具有一些逻辑以避免端子断开。

更换

func (w *ProxyWriter) Write(p []byte) (int, error) {
    // ... do something with bytes first
    fmt.Fprintf(w.file, "%s", string(p))
    return len(p), nil
}


fmt.Fprintf
有一些逻辑来避免终端断开。

我想你的意思是
w.file.Write
而不是
w.Write
?输出与
fmt.Fprintf
相同。很遗憾,您试过了吗?你什么意思
限定TTY
?是否出现中断的转义序列?是的,我尝试使用
返回w.file.Write(p)
。我所说的
限定为TTY
的意思是,如果我将os.Stdout包装在io.Writer接口中,并将
Cmd.Stdout
设置为它,它将不限定为终端。我理解你所说的
限定为终端的意思。因为它不是一个*os.File文件。也许这能帮上忙?我想你是指
w.file.Write
而不是
w.Write
?输出与
fmt.Fprintf
相同。很遗憾,您试过了吗?你什么意思
限定TTY
?是否出现中断的转义序列?是的,我尝试使用
返回w.file.Write(p)
。我所说的
限定为TTY
的意思是,如果我将os.Stdout包装在io.Writer接口中,并将
Cmd.Stdout
设置为它,它将不限定为终端。我理解你所说的
限定为终端的意思。因为它不是一个*os.File文件。也许这能帮上忙?