Это взято непосредственно из исходного кода функции prompt
ExtUtils :: MakeMaker. Возможно, я предполагаю, что кто-то может пойти на все, чтобы обмануть это. Но в какой-то момент поломка должна принадлежать выключателю.
Для большинства целей этого должно быть достаточно:
my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ;
Сначала проверяется, открыт ли STDIN для TTY. Если так, проверьте, является ли STDOUT. Если STDOUT нет, его также нельзя открывать ни в файл, ни в специальный символьный файл.
Обновление:
IO :: Prompt :: Tiny использует следующее:
# Copied (without comments) from IO::Interactive::Tiny by Daniel Muey,
# based on IO::Interactive by Damian Conway and brian d foy
sub _is_interactive {
my ($out_handle) = ( @_, select );
return 0 if not -t $out_handle;
if ( tied(*ARGV) or defined( fileno(ARGV) ) ) {
return -t *STDIN if defined $ARGV && $ARGV eq '-';
return @ARGV > 0 && $ARGV[0] eq '-' && -t *STDIN if eof *ARGV;
return -t *ARGV;
}
else {
return -t *STDIN;
}
}
И IO :: Interactive :: Tiny добавляет комментарии, чтобы объяснить, что происходит:
sub is_interactive {
my ($out_handle) = (@_, select); # Default to default output handle
# Not interactive if output is not to terminal...
return 0 if not -t $out_handle;
# If *ARGV is opened, we're interactive if...
if ( tied(*ARGV) or defined(fileno(ARGV)) ) { # IO::Interactive::Tiny: this is the only relavent part of Scalar::Util::openhandle() for 'openhandle *ARGV'
# ...it's currently opened to the magic '-' file
return -t *STDIN if defined $ARGV && $ARGV eq '-';
# ...it's at end-of-file and the next file is the magic '-' file
return @ARGV>0 && $ARGV[0] eq '-' && -t *STDIN if eof *ARGV;
# ...it's directly attached to the terminal
return -t *ARGV;
}
# If *ARGV isn't opened, it will be interactive if *STDIN is attached
# to a terminal.
else {
return -t *STDIN;
}
}
И я проверил, что логика в IO :: Interactive отражает логику IO :: Interactive :: Tiny. Итак, если ваша цель - подсказывать, где это уместно, рассмотрите возможность использования IO :: Prompt :: Tiny. И если ваши потребности более тонкие, чем поддерживает IO :: Prompt :: Tiny, вы можете использовать IO :: Interactive :: Tiny для предоставления этой специфической функциональности.
В то время как вы, вероятно, в основном используете безопасное собственное решение, преимущество использования одного из этих модулей CPAN состоит в том, что они, по-видимому, активно поддерживаются и будут получать только отчеты и возможные обновления, если они окажутся неадекватными их объявленной цели. .