【问题标题】:Is it possible to detect if a writer is tty or not?是否可以检测作者是否为 tty?
【发布时间】:2021-08-23 08:42:45
【问题描述】:

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

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

我可以看到彩色文本,但如果我将输出通过管道传输到文件,则颜色会保留,这不是我想要的。

顺便说一句,这个问题主要和Go无关,我只是想在我的go程序中实现效果。

【问题讨论】:

  • 在某些操作系统上是可能的。 Logrus 在各种 terminal_check* 文件中支持各种操作系统。
  • 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. - 这是 ls 功能,而不是 Bash

标签: go colors console tty


【解决方案1】:

Bash 有一个“神奇的行为”,如果你输入 'ls',通常你会 获得彩色输出,但如果将输出重定向到文件,则 颜色代码不见了。

这不是 Bash 功能,而是 ls 功能。它调用 isatty() 检查标准输出文件描述符是否引用终端。在 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")
        }
}

【讨论】:

  • 这确实有效。但是,我的代码是:func Dump(w io.Writer) { ... },所以,我可以简单地使用您的代码,加上一个包装器: if w == os.Stdout { ... }
  • 还有一个问题:这适用于 Windows 吗? github.com/mattn/go-isatty有一个叫做IsCygwinTerminal()的函数,这意味着tty-color是*nix系统(或带有模拟器的windows)的一个特性?
  • 我不知道,我不会用 Windows
猜你喜欢
  • 1970-01-01
  • 2014-09-03
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 2020-08-13
相关资源
最近更新 更多