以下のGo言語コードをyellow.exeという名前で保存していたとします

package main

import (
    "fmt"

    "github.com/fatih/color"
)

func main() {
    yellow := color.New(color.FgYellow).SprintFunc()
    fmt.Fprintf(color.Output, "< %s >\n", yellow("yellow"))
}

それを以下のようなコードで外部プログラム実行した場合、io.MultiWriter だと色が出力されません。

package main

import (
    "io"
    "os"
    "os/exec"
)

func main() {
    var cmd *exec.Cmd

    cmd = exec.Command(`yellow.exe`)
    cmd.Stdout = os.Stdout
    cmd.Run()

    cmd = exec.Command(`yellow.exe`)
    cmd.Stdout = io.MultiWriter(os.Stdout)
    cmd.Run()
}

この例ではos.Stdoutのみをio.MultiWriterに入れていますが、本来はファイルへの出力と同時に標準出力にも出力したいと考えていて、ファイルには色なしで出力し、標準出力には色付きで出力したいと考えています。また、外部プログラム実行をするプログラムはgo言語とは限らず、C#で作成したプログラムの場合もあり、外部プログラム側のコードはいじれない場合もあります。その場合にどのようにすれば、標準出力に色付きの出力をしつつ、ファイルにも同じ文字列を落とせるでしょうか?

========
追記(2018/07/10)

@metropolis さんのコメントを受けて、さらなる調査を行ったところ、一定条件下での解決策は出たと思います。以下にそれを記しておきます。

io.MultiWriterを標準出力に設定すると、ターミナルではないという判定になり、mattn/colorable が色設定をスキップするようなので、fatih/color 側の NoColorをチェックしtrueならエスケープ情報をそのまま標準出力に流し、親側に色情報を提供するようにしました。もしfalseなら生のターミナルにそのまま色情報を出力します。

package main

import (
    "fmt"
    "io"
    "os"

    "github.com/fatih/color"
)

func main() {
    c := color.New(color.FgYellow)
    var output io.Writer
    if color.NoColor {
        c.EnableColor()
        output = os.Stdout
    } else {
        output = color.Output
    }
    yellow := c.SprintFunc()
    fmt.Fprintf(output, "< %s >\n", yellow("yellow"))
}

親側はそれを受けて、標準出力はcolorable.NewColorable()で受けて、ファイルへの出力はcolorable.NewNonColorable()で受けてやることで、io.MultiWriterでも色設定をできるようにしました。

package main

import (
    "flag"
    "io"
    "os"
    "os/exec"

    colorable "github.com/mattn/go-colorable"
)

var c = flag.String("c", "yellow.exe", "")

func main() {
    flag.Parse()
    var cmd *exec.Cmd

    cmd = exec.Command(*c)
    cmd.Stdout = colorable.NewColorable(os.Stdout)
    cmd.Run()

    f, _ := os.Create("yellow.txt")
    defer f.Close()

    cmd = exec.Command(*c)
    cmd.Stdout = io.MultiWriter(colorable.NewNonColorable(f), colorable.NewColorable(os.Stdout))
    cmd.Run()
}

親子がGo言語で書ける 且つ 子のコードを編集可能 である場合に限り、この対応で問題ないと思いますが、これ以外の場合においては、いまだ解決策がない状態です。