Testing Whether a Program Is Running Interactively
Problem
You want to know whether your program is being called interactively or not. For instance, a user running your program from a shell is interactive, whereas the program being called from cron is not.
Solution
Use -t
to test STDIN
and
STDOUT
:
sub I_am_interactive { return -t STDIN && -t STDOUT; }
If you’re on a POSIX system, test process groups:
use POSIX qw/getpgrp tcgetpgrp/; sub I_am_interactive { local *TTY; # local file handle open(TTY, "/dev/tty") or die "can't open /dev/tty: $!"; my $tpgrp = tcgetpgrp(fileno(TTY)); my $pgrp = getpgrp(); close TTY; return ($tpgrp == $pgrp); }
Discussion
The -t operator tells whether the
filehandle or file is a tty device. Such devices are signs of
interactive use. This only tells you whether your program has been
redirected. Running your program from the shell and redirecting STDIN
and STDOUT makes the -t version of
I_am_interactive
return false. Called from
cron, I_am_interactive
also
returns false.
The POSIX test tells you whether your program has exclusive control
over its tty. A program whose input and output has been redirected
still can control its tty if it wants to, so the POSIX version of
I_am_interactive
returns true. A program run from
cron has no tty, so
I_am_interactive
returns false.
Whichever I_am_interactive
you choose to use,
here’s how you’d call it:
while (1) { if (I_am_interactive()) { print "Prompt: "; } $line = <STDIN>; last unless defined $line; # do something with ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.