Go Proxy exec.Cmd Stdout/Stderr而不丢失TTY
我有以下代码,它执行任意shell命令并将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
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文件。也许这能帮上忙?