我可以检测一个Perl脚本正在从肯定的终端上运行?

问题描述 投票:1回答:3

我可以检测一个Perl脚本正在从肯定的终端上运行?

我宁愿违约的假设,它已经从浏览器中运行,如果我不知道。但是,如果有一种方法,以确保它已100%从终端上运行,我会(用于调试)高兴。

非常感谢

perl environment-variables
3个回答
3
投票

使用该测试的文件句柄是否被连接到终端file test operator -t。例如:

if (-t STDIN) {
  print "Running with a terminal as input."
}

3
投票

这是直接从参考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模块之一是,他们大概是积极维护,并会接受,但报告和最终的更新,如果他们变成不足以标榜自己的目的。


1
投票

设备文件/dev/tty表示用于过程控制终端。如果你的进程没有连接到终端(守护进程,走出cron / at等),那么就不能“开放”这个特殊的设备。所以

sub isatty {
    no autodie;
    return open(my $tty, '+<', '/dev/tty');
}

所述/dev/tty可以代表虚拟控制台装置(/dev/ttyN),PTY(xtermssh),串口(COM1)等,并且不受重定向,所以这应该是可靠的。

如果运行速度非常或者经常使用这个版本

use feature qw(state);

sub isatty { 
    no autodie; 
    state $isatty = open(my $tty, '+<', '/dev/tty'); 
    return $isatty;
}

这应该是更有效率(超过幅度在我简单的基准级)。

在Unix-Y系统仅这些工作(或在Windows上运行的应用程序的POSIX,或在窗口的POSIX子系统)。

© www.soinside.com 2019 - 2024. All rights reserved.