1

我有一个 perl 脚本,它通过 SSH 在某些 PC 上远程运行命令。所以我想将所有电脑上的时间设置为相同。PC 是基于 linux 的系统,perl 脚本使用另一个 .txt 文件,该文件具有要执行的命令。但是当我运行 perl 脚本时,出现以下错误:

Command = date --set "27 SEP 2012 19

sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file

perl 脚本工作正常,因为我尝试了另一个命令并给出了结果。那么什么可能导致这个错误。

perl代码是:

#!/usr/bin/perl

open (MYFILE,'HostIPWithCmd.txt');
$i=0;
 @IPs=<MYFILE>;
 foreach (@IPs) {
chomp;
($EthIP,$Cmd)= split(":");
 if($EthIP!=~ ("#"))
 {
    push(@hostIP,$EthIP);
    push(@destCmd,$Cmd);

 }

 else
 {
   push(@hostIP,"$EthIP");
   push(@destCmd,$Cmd);
 }
}

$i=0;

foreach my $host (@hostIP)
{
   if($host !=~ ("#"))
   {

      my @cmds= split(/,/,$destCmd[$i]);
      print "\n\nCommands For $host = $destCmd[$i]\n";


   foreach my $command (@cmds)
             {
 print "\n*************************************";
 print "\nCommand = $command \n\n";
 system("ssh -o ConnectTimeout=10 $host $command");

         }

  print "\n***** End Of Host : $host  *****\n";
  print "************************************************************\n\n";
      }

 $i++;
}

和 HostIPWithCmd.txt

   10.20.146.97:date --set "27 SEP 2012 19:00:00"

提前致谢。

4

1 回答 1

4

这很简单。这是因为您的字符串中的其他位置有冒号,这会导致字符串的结尾消失。该声明:

($EthIP,$Cmd)= split(":");

输入:

10.20.146.97:date --set "27 SEP 2012 19:00:00"

将产生:

$EthIP = '10.20.146.97';
$Cmd   = 'date --set "27 SEP 2012 19';

拆分列表的其余部分(被丢弃)将是:

@rest = ("00", "00");

因为你在冒号上分裂:。一个简单的解决方法是有一个限制:

($EthIP,$Cmd)= split(/:/, $_, 2);  # max 2 fields

---

但是,即使使用此修复程序,您的代码也可以正常工作是值得怀疑的。您的代码中有很多严重的错误。从上到下:

  • 你不使用use strict; use warnings;这是一个重大错误,因为它会让你在代码中出现无声警告和拼写错误(参见下面的示例)。永远不要在没有这两个 pragma 的情况下编写 perl 代码。
  • 您使用open语句而不检查返回值,例如open MYFILE, 'HostwithIP.txt' or die $!. 不检查返回值会让打开静默失败,造成各种麻烦。不使用warnings不会警告您正在从关闭的文件句柄中读取,并且您将整天坐在那儿挠头,然后才弄明白。
  • 您将两个参数 open 与全局文件句柄一起使用。您应该使用显式打开模式和词法文件句柄。例如open my $fh, "<", 'HostIPWithCmd.txt" or die $!
  • 您正在使用foreach (@IP)而不是简单地迭代文件句柄,例如while (<MYFILE>)
  • split使用正则表达式,而不是字符串。它将字符串转换为正则表达式,但最好从一开始就这样做。split /#/.
  • 没有!=~操作员。它将被解释为$foo != ~ $bar,或者换句话说, 和 之间的数值不等式$foo检查$bar。您想要的运算符是!~. 这个特殊的东西会把你的代码分解成很多小块,特别是当你不使用warnings时,错误是无声的。所以不,正如你在评论中所说,你的脚本不能完美运行,它被严重破坏了。您只是看不到它,因为您不使用warnings.
  • 您的 if-else 语句是完全多余的,因为在 if 和 else 子句中都会发生同样的事情。$EthIP和之间没有区别"$EthIP"。两者完全相同。这可能是您认为您的代码有效的原因。

此外,在使用时system,反引号或qx()考虑其他解决问题的方法总是一个好主意。有些模块可以比system.

于 2012-09-27T18:50:38.857 回答