Recipe 15.2 Testing Whether a Program Is Running Interactively
15.2.1 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.
15.2.2 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 {
my $tty;
open($tty, "<", "/dev/tty") or die "can't open /dev/tty: $!";
my $tpgrp = tcgetpgrp(fileno($tty));
my $pgrp = getpgrp( );
close $tty;
return ($tpgrp = = $pgrp);
}
15.2.3 Discussion
The
-t file test 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 the line
}
Or, more clearly:
sub prompt { print "Prompt: " if I_am_interactive( ) }
for (prompt( ); $line = <STDIN>; prompt( )) {
# do something with the line
}
15.2.4 See Also
The documentation for the standard POSIX module, also in Chapter 32
of Programming Perl; the -t
file test operator in Chapter 3 of Programming
Perl and in perlop(1)
|