我可以确定是否从终端运行Perl脚本吗?
如果不确定,我宁愿默认假定它是从浏览器运行的。但是,如果有办法确保它已经从终端运行了100%,我会很高兴(出于调试目的)。
非常感谢
答案 0 :(得分:3)
使用file test operator -t
测试文件句柄是否已附加到终端。例如:
if (-t STDIN) {
print "Running with a terminal as input."
}
答案 1 :(得分:3)
这直接来自ExtUtils :: MakeMaker的prompt
函数的源代码。我想,有人可能会竭尽全力去欺骗它。但是在某些时候,破损必须归破碎者所有。
对于大多数目的,这应该足够了:
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模块的一个优点是,它们大概处于主动维护状态,并且如果结果证明不符合其广告目的,则会收到报告和最终更新。
答案 2 :(得分:1)
设备文件/dev/tty
代表该过程的控制终端。如果您的进程未连接到终端(守护程序,cron
/ at
中的守护程序等),则它无法“打开”此特殊设备。所以
use feature qw(state);
sub isatty {
no autodie;
state $isatty = open(my $tty, '+<', '/dev/tty');
return $isatty;
}
/dev/tty
可以代表虚拟控制台设备(/dev/ttyN
),pty(xterm
,ssh
),串行端口(COM1)等,并且不受影响通过重定向,所以这应该可靠。
上面的代码仅比simple(r)
有效sub isatty {
no autodie;
return open(my $tty, '+<', '/dev/tty');
}
因此,如果不经常使用该版本,第二个版本就可以了。
仅在Unix-y系统上(或在Windows之上运行的POSIX应用程序中,或在Window的POSIX子系统中)工作。