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

时间:2011-08-05 10:56:10

标签: linux perl tty

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

也就是说,我需要代码:

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

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

信息似乎确实可用。如果我运行ps,则会在pts/2列中显示TTY条目,即使我运行./myscript.pl </dev/null >/dev/null 2>/dev/null,也会在作为cron作业运行时显示?或CGI脚本。

在Perl脚本中是否有一种优雅的方法来确定它?我宁愿不必解析ps的输出。

5 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分: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";
    }
}

答案 2 :(得分:1)

PS应该帮助你。
ps aux | grep 'filename.pl'

答案 3 :(得分:0)

要部分回答我自己的问题,以下是诀窍:

sub isatty()
{
    my $tty = `/bin/ps -p $$ -o tty --no-headers`;
    $tty =~ s{[\s?]}{}g;
    return $tty;
}

返回TTY名称(如果有)(如果为true),或者“”如果没有(false)。

我还是更喜欢没有外部命令的解决方案...

答案 4 :(得分:0)

首先你必须检查,输出与-t相关联。当然如果你想,你可以查看/ proc / $ pid / fd / 1,它是设备的符号链接。如果它是终端,你可以测试它。

但如果还不够,可以通过%ENV特殊哈希表检查环境变量。 CGI-BIN接口设置了其中一些。如果你在cron下运行脚本,它会设置一些变量。如果还不够,可以在/ etc / crontab文件中设置它并在脚本中进行测试。它可以满足您的需求。

您应该只调用一次完整的程序。你不能迭代它,因为脚本环境不会改变,直到它工作。

您不必调用任何外部命令,或者您不需要特殊的libarier。只有你需要的是Windows不兼容。但是如果你使用的是windows10,那么它的环境类似于基于ubuntu的linux。那么你就不能强烈关注,就像你在win32api和unix之类的系统之间建立兼容性一样。