Home / Alt manpages / tty(1)

  • tty(1)
  • User command
  • linux

Check Whether Standard Input Is a Terminal with tty

You will finish with a small, reliable check for the terminal connected to standard input. The same command can print the terminal device, or return only a success or failure status for use in a shell condition. This guide uses GNU tty from coreutils 9.4, installed here as package version 9.4-3ubuntu6.3.

Allow about ten minutes. You need a shell and the coreutils package. No elevated privileges are needed, and this guide changes no files, services or terminal settings.

1. Confirm the installed command

Check the binary and its version before relying on a script or a copied example. These are ordinary read-only commands:

$ command -v tty
/usr/bin/tty
$ tty --version
tty (GNU coreutils) 9.4
...
$ dpkg-query -W -f='\${Package} \${Version}\n' coreutils
coreutils 9.4-3ubuntu6.3

The local manual describes tty as printing the file name of the terminal connected to standard input. It is not a general test of whether a graphical terminal application is open, and it does not inspect standard output.

Checkpoint

The command you are about to run is GNU coreutils tty, not a shell alias or a different utility earlier in your PATH.

2. Print the terminal device

Run tty at a normal interactive shell prompt:

$ tty
/dev/pts/1

Your number will probably differ. A path such as /dev/pts/1 identifies the pseudo-terminal attached to the shell. A hardware console may produce a path such as /dev/tty1. Treat the output as host-specific rather than something to hard-code.

The result is useful when a script needs to show where its input is coming from, or when you are diagnosing why an interactive program behaves differently from a scheduled or redirected invocation. The command prints a line only when standard input is a terminal. Its exit status also matters, so do not parse the device path when a simple yes-or-no test is enough.

3. Test terminal input without printing

Use -s, also available as --silent and --quiet, when the caller needs only a status:

$ if tty --silent; then
>     echo 'standard input is a terminal'
> else
>     echo 'standard input is not a terminal'
> fi
standard input is a terminal

In this mode tty prints nothing. Exit status 0 means that standard input is connected to a terminal; a non-zero status means it is not. In the example above, the shell's if consumes the status and prints its own message.

For a compact guard, use the same test before an interactive action:

if ! tty -s; then
    printf '%s\n' 'This command needs an interactive terminal.' >&2
    exit 1
fi
printf '%s\n' 'Interactive input is available.'

This test does not grant access to a terminal and does not convert redirected input into interactive input. It only reports the state of standard input at the moment it runs.

Checkpoint

Use tty -s in conditions. Use plain tty only when you actually need the device name.

4. See the difference when input is redirected

A pipe gives the next command the pipe as standard input, so tty should report that there is no terminal:

$ printf '%s\n' 'input from a pipe' | tty
not a tty
$ printf 'tty exit status: %s\n' "\${PIPESTATUS[1]}"
tty exit status: 1

The wording not a tty is diagnostic output from GNU tty. The non-zero status is the stable result that a shell condition should use. PIPESTATUS is a Bash array, so do not copy that status check unchanged into a shell that does not provide it.

For a portable, direct check in a script, keep the command outside a pipeline:

if tty -s </path/to/input.txt; then
    echo 'unexpected terminal input'
else
    echo 'input is redirected or otherwise not a terminal'
fi

Replace /path/to/input.txt with a real readable file. This example changes no data. It demonstrates that shell redirection decides what tty sees as standard input.

5. Avoid the common script traps

Do not test terminal state by checking whether tty printed a path. That breaks when output is redirected and needlessly mixes presentation with control flow. Prefer tty -s and its exit status.

Do not assume that a terminal is attached merely because standard output is visible. A command can receive input from a file while still writing messages to a terminal, or it can have both input and output redirected. This guide concerns standard input only.

Do not add sudo. Asking about the current process's input is an unprivileged operation. Elevated privileges will not turn a pipe, file or closed descriptor into a terminal.

Be careful when testing from automation. A job launched by cron, a service manager or a pipeline normally has no terminal on standard input. That is expected, not a permission error. If an interactive prompt is required, arrange the input and terminal allocation in the system that launches the job, then test that launcher separately.

6. Understand the available options

The installed command has a deliberately small interface:

  • -s, --silent and --quiet suppress the device-name output and leave the result in the exit status.
  • --help prints the usage summary and exits.
  • --version prints version information and exits.

There is no option here to select a different file descriptor, configure a terminal, or force success. If a program needs to test another descriptor, use the shell's redirection or the programming interface appropriate to that program. Do not invent a tty option for the job.

Done means

  • tty reports the terminal device connected to standard input when run interactively.
  • tty -s produces no output and returns success only when standard input is a terminal.
  • You have tested the redirected-input case and understand its non-zero status.
  • Your script checks the exit status instead of parsing host-specific device names or messages.
  • No elevated privilege or persistent configuration change was needed.