Is it possible to detect if a writer is tty or not?

Viewed 963

Bash has a 'magical behavior', if you type 'ls', usually you will get colorful output, but if you redirect the output to a file, the color codes are gone. How to achive this effect using Go. e.g. With the following statement:

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

I can see the text in color, but if I pipe the output to a file, the color is preserved, which is NOT what I want.

BTW, this question is mostly not related to Go, I just want to achive the effect in my go program.

1 Answers

Bash has a 'magical behavior', if you type 'ls', usually you will get colorful output, but if you redirect the output to a file, the color codes are gone.

It's not Bash feature, it's ls feature. It calls isatty() to check if stdout file descriptor refers to a terminal. In musl libc isatty is implemented like that:

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;
}

You can use the same method in 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")
        }
}
Related