1
我已经得到下面的代码执行的任意的外壳命令和管道的stdout
和stderr
到终端。:代理exec.Cmd标准输出/标准错误,而不会失去TTY
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状态?
我假设你的意思是'w.file.Write'而不是'w.Write'?不幸的是,输出与'fmt.Fprintf'相同。 – kbirk
你试过了吗?你是什么意思'限定TTY'?出现破坏的转义序列? – mattn
是的,我尝试使用'返回w.file.Write(p)'。我认为'符合TTY'的意思是,如果我将os.Stdout包装在一个io.Writer接口中,并将'Cmd.Stdout'设置为它,它将*不符合终端。 – kbirk