如何从perl脚本执行perl命令(正确转义)

我有一个Perl脚本,我需要在远程主机上执行一个简单的perl命令:

ssh 192.168.1.1 "perl -pi.bup -e 's/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/' /etc/grub.conf" 

这只是简单地将“ audit=1 ”添加到/etc/grub.conf中每个内核行的末尾(如果它尚不存在)。

单线程在主机上直接运行时工作得很好,但不能通过另一个perl脚本中的ssh执行。 我试图用一个或多个反斜杠来逃避所有的美元符号,我也试图逃避“ \s ”中的反斜杠,但我似乎没有任何工作。

注意我不想将脚本复制到远程主机,然后执行它 – 我想直接使用ssh命令来执行它。

如何正确地逃避这一点,使其工作?

– 2015年9月9日更新,以显示我在做的Perl脚本:

 sub SomeMethod { &RunCommand($host, "perl -pi.bup -e \'s/^(\s+?kernel)(.*)(?<!audit=1)\$/\$1\$2 audit=1/\' /etc/grub.conf"); } sub RunCommand { my ($server, $command) = @_; my $commandOutput = ""; if ($server ne "") { $command = "ssh $server \"$command\""; } $commandOutput = `$command`; print $commandOutput; if (($? >> 8) != 0) { &LogMessage ("$command failed:\n\n$commandOutput"); return $commandOutput; } return $commandOutput; } 

– 更新#2,使用system而不是back-ticks:

 system 'ssh', $host, 'perl', '-pi.bup', '-e', 's/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/', '/etc/grub.conf'; bash: -c: line 0: syntax error near unexpected token `(' bash: -c: line 0: `perl -pi.bup -es/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/ /etc/grub.conf' 

好的,我可以在这里使用系统,但如何正确地逃脱它?

由于您正在编辑远程文件,因此不需要捕获输出,因此system比使用反引号更好:

 system 'ssh', '192.168.1.1', 'perl', '-pi.bup', '-e', 's/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/', '/etc/grub.conf'; 

请注意,您不必将远程命令作为单个parameter passing给ssh。 这有助于引用一点。 如果你真的想,你可以:

 system 'ssh', '192.168.1.1', q{perl -pi.bup -e 's/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/' /etc/grub.conf}; 

使用q{}运算符允许perl单行使用单引号。


实际上,我会这样做:

 use Try::Tiny; use IPC::System::Simple qw{capture}; sub SomeMethod { my $output = RemoteCommand( $host, q{perl -pi.bup -e 's/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/' /etc/grub.conf} ); } sub RemoteCommand { my ($server, $command) = @_; my $output; try { $output = capture('ssh', $server, $command); } catch { LogMessage("command failed: ($command) : $_"); $output = $_; }; return $output; } 

我终于搞定了。

直接从bash:

 echo 's/^(\s+?kernel)(.*)(?<!audit=1)$/$1$2 audit=1/' | ssh 192.168.1.1 "perl -pi.bup - /etc/grub.conf" 

从Perl脚本:

 my $command = "echo 's/^(\\s+?kernel)(.*)(?<!audit=1)\$/\$1\$2 audit=1/' | ssh $_wsAddress 'perl -pi.bup - /etc/grub.conf' "; &RunCommand("", $command); 

我尝试了以下简单的命令,它的工作原理

 ssh localhost "sed -i.bck '/[^audit]/{s/\(^\s\+kernel.*\)/\1 audit=1/g}' /boot/grub/menu.lst" 

不是关于sed vs perl ,而是使用前面的命令更清楚地归档你想要的。