Go语言 是否可以检测一个writer是否是tty?

dzhpxtsq  于 2023-03-21  发布在  Go
关注(0)|答案(2)|浏览(397)

Bash有一个“神奇的行为”,如果你输入“ls”,通常你会得到彩色的输出,但是如果你把输出重定向到一个文件,颜色代码就消失了。如何用Go语言实现这个效果。例如,用下面的语句:

fmt.Println("\033[1;34mHello World!\033[0m")

我可以看到彩色文本,但是如果我将输出通过管道传输到文件,颜色会 * 保留 *,这不是我想要的。
顺便说一句,这个问题大多和围棋无关,我只是想在我的围棋程序中达到效果。

zu0ti5jz

zu0ti5jz1#

Bash有一个“神奇的行为”,如果你输入“ls”,通常你会得到五颜六色的输出,但如果你重定向输出到一个文件,颜色代码消失了。
这不是Bash特性,这是ls特性。它调用isatty()来检查stdout文件描述符是否引用了一个终端。在musl libc中,isatty是这样实现的:

int isatty(int fd)
{
        struct winsize wsz;
        unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz);
        if (r == 0) return 1;
        if (errno != EBADF) errno = ENOTTY;
        return 0;
}

在Go语言中也可以使用同样的方法:

package main

import (
        "fmt"
        "os"

        "golang.org/x/sys/unix"
)

func main() {
        _, err := unix.IoctlGetWinsize(int(os.Stdout.Fd()), unix.TIOCGWINSZ)
        if err != nil {
                fmt.Println("Hello World")
        } else {
                fmt.Println("\033[1;34mHello World!\033[0m")
        }
}
91zkwejq

91zkwejq2#

我只是通过复制@ptx注解来回答,这是更规范的答案:
更好的方法是从x/term使用term.isTerminal。它在windows上工作,由golang团队维护
这是为了提高可见性,因为这个答案是可移植的,并且不添加外部依赖项。

相关问题