我可以检测一个Perl脚本正在从肯定的终端上运行?
我宁愿违约的假设,它已经从浏览器中运行,如果我不知道。但是,如果有一种方法,以确保它已100%从终端上运行,我会(用于调试)高兴。
非常感谢
使用该测试的文件句柄是否被连接到终端file test operator -t
。例如:
if (-t STDIN) {
print "Running with a terminal as input."
}
这是直接从参考ExtUtils的源代码:: MakeMaker的的prompt
功能拍摄。这是可能的,我想,有人可能去的长度,以欺骗它。但在某些时候破损必须由断路器所拥有。
在大多数情况下这应该是足够的:
my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ;
首先,它会检查是否STDIN被打开到TTY。如果是这样,检查标准输出。如果stdout不是,它也必须既不能打开一个文件,也不是一个字符特殊文件。
更新:
IO ::提示::微小使用下列内容:
# 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 ::互动::微小的增加注释来解释发生了什么:
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 ::交互逻辑反映的是IO ::互动::微小的。所以,如果你的目标是促使在适当情况下,可以考虑使用IO ::提示::微小。如果你的需求是更细致的比IO ::提示::微小的支持,你可以使用IO ::互动::微小的提供这种特定的功能。
当你使用自己的解决方案很可能主要是安全,一个优势,使用这些CPAN模块之一是,他们大概是积极维护,并会接受,但报告和最终的更新,如果他们变成不足以标榜自己的目的。
设备文件/dev/tty
表示用于过程控制终端。如果你的进程没有连接到终端(守护进程,走出cron
/ at
等),那么就不能“开放”这个特殊的设备。所以
sub isatty {
no autodie;
return open(my $tty, '+<', '/dev/tty');
}
所述/dev/tty
可以代表虚拟控制台装置(/dev/ttyN
),PTY(xterm
,ssh
),串口(COM1)等,并且不受重定向,所以这应该是可靠的。
如果运行速度非常或者经常使用这个版本
use feature qw(state);
sub isatty {
no autodie;
state $isatty = open(my $tty, '+<', '/dev/tty');
return $isatty;
}
这应该是更有效率(超过幅度在我简单的基准级)。
在Unix-Y系统仅这些工作(或在Windows上运行的应用程序的POSIX,或在窗口的POSIX子系统)。