---
title: Executables can Introspect their Output Destination
teaser: 'Sometimes, a programs output will depend on where it is sending that output.

  '
tags: til,unix,shell
author: Sid Raval
published_on: 2019-12-06
---

Usually, when I type:

```bash
$ git log --oneline --graph
```

I see something like this:

![git log output with ref names and color output](https://images.thoughtbot.com/blog-vellum-image-uploads/BCwpfkLlSO1W5fOGqyI1_Screen%20Shot%202019-11-22%20at%202.48.36%20PM.png)

But recently, I typed:

```bash
$ git log --oneline --graph | head -15
```

And I saw this:

![git log output without ref names and uncolored output](https://images.thoughtbot.com/blog-vellum-image-uploads/6aHbAEgQC6Qr2jzyBH51_Screen%20Shot%202019-11-22%20at%202.54.03%20PM.png)

I was confused why the output differed; to my knowledge, `head` did not alter
its input at all. And indeed, it doesn't - but `git log` _does_ alter its output
depending on whether or not the output is a TTY. It does this via [`isatty(3)`].

Since `git` v2.13, `git log` gets a `--decorate=auto` default. The documentation
for `git log --decorate` reads:

> If auto is specified, then if the output is going to a terminal, the ref names
> are shown as if short were given, otherwise no ref names are shown. The
> default option is short.

Since `head` is not a TTY, the ref names & color codes are omitted from the
output of `git log`.

You can see the call to `isatty(3)` in the [`git log` source].

[`isatty(3)`]: http://man7.org/linux/man-pages/man3/isatty.3.html
[`git log` source]: https://github.com/git/git/blob/v2.24.0/builtin/log.c#L68
