如何检查Perl脚本是否在终端中运行?

msc*_*cha 9 linux perl tty

我试图在Linux上的Perl脚本中确定它是否在终端中运行.

也就是说,我需要以下代码:

  • 只需在命令行上运行即可返回true
  • 运行时./myscript.pl | less甚至还会返回true./myscript.pl </dev/null >/dev/null 2>/dev/null
  • 在cron作业中运行时返回false,或作为CGI脚本返回false

特别是因为第二个子弹,我不能使用-t STDOUT和变化,IO :: Interactive也没用.

信息似乎确实可用.如果我运行ps,它显示的条目类似pts/2TTY专栏,甚至当我运行./myscript.pl </dev/null >/dev/null 2>/dev/null,并?作为cron作业或CGI脚本运行的时候.

有没有一种优雅的方法来在Perl脚本中确定这个?我宁愿不必解析输出ps.

Ing*_*ngo 12

您可以尝试打开/ dev/tty.如果您在终端(即使在远程计算机上的终端中),这将有效.否则,如果脚本是通过at或cron运行的,则不会.

注意:这只适用于Unix系统.

  • @Ingo,这没有必要,因为他使用了一个词法文件句柄而没有返回它.因此,当变量超出范围时(当`isatty`返回时),文件句柄将自动关闭. (6认同)
  • 更高效的版本,如果经常这样运行:`sub isatty(){no autodie; state $ isatty = open(my $ tty,'+ <','/ dev/tty'); return $ isatty; }`.这就是我要去的那个. (3认同)

msc*_*cha 5

我自己的问题的另一个答案.我研究了ps源代码,看看它是如何确定TTY的,并且它使用了/proc/[pid]/stat.

use strict;
use warnings;
use 5.010;
use autodie;

sub isatty()
{
    # See http://www.kernel.org/doc/man-pages/online/pages/man5/proc.5.html
    open(my $stat, '<', "/proc/$$/stat");
    if (<$stat> =~ m{^\d+\s+\(.*\)\s+\w\s+\d+\s+\d+\s+\d+\s+(\d+)}) {
        return $1 > 0;
    }
    else {
        die "Unexpected format in /proc/$$/stat";
    }
}
Run Code Online (Sandbox Code Playgroud)