C言語とGo言語で標準出力が端末を参照しているかどうかを判定する

標準出力のディスクリプタを取得して、それが端末を参照しているかどうかを判定する。 使いどころは端末に出力する時と、ファイルにリダイレクト出力する時とで表示の仕方を変えたいとき。

例えば、以下のページの方法でターミナルの文字をカラーにできる。

C言語でターミナルで表示される文字をカラー表示させる

だけど、これをファイルにリダイレクト出力するとエスケープシーケンスまで記録されてしまい、非常に見づらくなる。
そこで、標準出力がどこに出力されるかを判定し、カラーのON/OFFを切り替える処理を入れるようにしたい。

出力先が端末かどうかの判定は、Cだとこう書く。

#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = fileno(stdout);
    int isTerminal = isatty(fd);
    printf("fd=%d, isTerm=%d\n", fd, isTerminal);
    return 0;
}


Goだとこう書く。
Cのisatty()の代わりになる関数が公式パッケージにはなかったので、 http://godoc.org/code.google.com/p/go.crypto/ssh/terminal
IsTerminal()を使用。

package main

import (
    "fmt"
    "os"
    term "code.google.com/p/go.crypto/ssh/terminal"
)

func main() {
    fd := os.Stdout.Fd()
    isTerminal := term.IsTerminal(int(fd))
    fmt.Printf("fd=%v, isTerm=%v\n", fd, isTerminal)
}

agはどうやって表示の切り替えをやってるんだろうとコード調べたのがきっかけ。 勉強になった。

参考