Perl在指定时间执行命令

时间:2014-06-27 17:06:50

标签: perl perl-module

我需要编写一个在指定时间执行命令的perl脚本。

  1. 使用net :: ssh :: expect登录路由器
  2. 从路由器的时钟读取时间(" show clock"命令显示时间。)
  3. 在17:30:00执行命令。
  4. 我尝试为它编写脚本,但它不起作用。有什么建议吗?

    use strict;
    use warnings;
    use autodie;
    use feature qw/say/;
    use Net::SSH::Expect;
    
    my $Time;
    my $ssh = Net::SSH::Expect->new(
        host     => "ip",
        password => 'pwd',
        user     => 'user name',
        raw_pty  => 1,
    );
    
    my $login_output = $ssh->login();
    
    while(1) {
        $Time = localtime();
        if( $Time == 17:30:00 ) {
            my $cmd = $ssh->exec("cmd");
            print($cmd);
        } else {
            print" Failed to execute the cmd \n";
        }
    }
    

2 个答案:

答案 0 :(得分:2)

这里有几件事:

首先,使用Time::Piece。它现在包含在Perl中。

use Time::Piece;
for (;;) {                   # I prefer using "for" for infinite loops
    my $time = localtime;    # localtime creates a Time::Piece object

    # I could also simply look at $time
    if ( $time->hms eq "17:30:00" ) {
        my $cmd $ssh->exec("cmd");
        print "$cmd\n";
    }
    else {
        print "Didn't execute command\n";
    }
}

其次,你不应该使用这样的循环,因为你将一遍又一遍地循环一个进程。你可以尝试睡到正确的时间:

use strict;
use warnings;
use feature qw(say);
use Time::Piece;

my $time_zone = "-0500";    # Or whatever your offset from GMT
my $current_time = local time;
my $run_time = Time::Piece(
    $current_time->mdy . " 17:30:00 $time_zone",   # Time you want to run including M/D/Y
     "%m-%d-%Y %H:%M:%S %z");                      # Format of timestamp
sleep $run_time - $current_time;
$ssh->("cmd");
...

我在这里做的是计算你想要运行命令的时间和你想要执行命令的时间之间的差异。只有在我当地时间下午5:30之后运行此脚本才会发出。在这种情况下,我可能要检查第二天。

或者,更好的是,如果您使用的是Unix,请查找crontab并使用它。 crontab将允许您准确指定应该执行特定命令的时间,并且您不必担心在程序中计算它。只需在crontab表中创建一个条目:

30 17 * * *  my_script.pl

3017表示您希望每天下午5:30运行脚本。其他星号表示月份,月份和星期几。例如,您只想在工作日运行程序:

30 17 * * 1-5  my_script.pl  # Sunday is 0, Mon is 1...

Windows有一种称为“计划控制面板”的类似方法,您可以在其中设置在特定时间运行的作业。您可能必须使用perl my_scipt.pl,因此Windows知道使用Perl解释程序来执行您的程序。

我强烈建议您使用 crontab 路由。它是高效的,保证工作,让你专注于你的程序,而不是在执行你的程序时。此外,它很灵活,每个人都知道,当它坐在那里并等待下午5:30时,没有人会杀死你的任务。

答案 1 :(得分:1)

localtime将Unix时间戳(自纪元以来的秒数,现在约为14亿)转换为值列表。 time函数可以方便地提供时间戳。来自perldoc -f localtime

Converts a time as returned by the time function to a 9-element
        list with the time analyzed for the local time zone. Typically
        used as follows:

            #  0    1    2     3     4    5     6     7     8
            ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                                        localtime(time);

您可以进行时间比较:

$Time = join ':', (localtime(time))[2, 1, 0];
if ($Time eq '17:30:00') {
    ...
}

由于Perl允许postcircumfix [...]运算符像对数组一样索引到列表中,我们可以使用它来删除包含小时,分钟和秒的(本地时间(时间))列表的片段,用冒号连接它们,并将结果字符串分配给$ Time。

请注意,由于$ Time现在包含一个字符串,因此您应将其与'17:30:00'进行比较,而不是将其与17:30:00进行比较,后者不是有效的数字形式,应该会导致编译错误。由于我们正在比较字符串而不是数字,因此我们使用eq运算符。 ==强制其操作数上的数字上下文,并且由于17:30:00不是有效数字,Perl会将其视为0并用

警告您
Argument "foo" isn't numeric in numeric eq (==) at ....