2014-06-27 34 views
-2

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

  1. 使用净:: SSH ::希望登录到路由器
  2. 从路由器的时钟读取的时间(“显示时钟”命令显示的时间。)
  3. 在17:30:00执行一个命令。

我试过为它编写脚本,但它不起作用。有什么建议吗?

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

我很确定它不起作用,它甚至没有编译。我认为你需要尝试更多... – jcaron

+0

出于好奇,为什么不为Windows的* nix或任务调度器cron? – Hambone

+0

@ Chris Hamel:这个perl脚本将与另一个perl脚本集成。所以我不想设置CRON。 – user3784022

回答

1

localtime转换Unix时间戳(秒因为时代,这是约1.4十亿现在),以值的列表。 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会用

Argument "foo" isn't numeric in numeric eq (==) at .... 
2

几件事情在这里把它当作0和警告你:

一,用途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。