Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

If I am running a reverse TCP shell and attempt to run su, I get the following message:

su: must be run from a terminal

I would like to emulate this behavior in my own program and am wondering how do I detect if a program is being run from a terminal?

share|improve this question
Call isatty with STDIN – Ulrich Dangel Mar 21 '13 at 17:39
up vote 6 down vote accepted

In a shell script:

if [ -t 0 ]; then
  echo stdin is a terminal

In a perl script:

print "stdin is a terminal\n" if -t;

In C:

if (isatty(0)) puts("stdin is a terminal");

They all do the same, do a tty specific ioctl and return true unless the ioctl fails with a ENOTTY error. On my system, the ioctl is TCGETS and I believe it's fairly common as it's an obvious one.

$ : | strace -e ioctl su
ioctl(0, TCGETS, 0x7ffff32dfc50) = -1 ENOTTY (Inappropriate ioctl for device)
su: must be run from a terminal
share|improve this answer
Regarding the C solution, it's fine, but don't use puts() and friends. The printf() family is recommended. – schaiba Mar 21 '13 at 23:46
@schaiba, Why? Even gcc optimises printf("stdin is a terminal\n") to puts("stdin is a terminal") even without any -O flag. – Stéphane Chazelas Mar 22 '13 at 8:04

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.