有人可以帮助我。我即将疯狂地看着这一行。我正在尝试使用perl -pi -e来编辑XML文件。
system("ssh -t <HOST> \"sudo su - root -c 'perl -pi -e 's/xmlNamespaceAware=\"false\">/xmlNamespaceAware=\"false\"><Alias>$virtualhost1<\/Alias>/g' /home/harrikr/Scripts/TcServerScripts/data.xml'\"");
这不起作用我尝试了所有类型的组合。
答案 0 :(得分:3)
你已经问了这个问题,答案是你引用的所有内容都混淆了。这就是你拥有的:
"ssh -t <HOST> \"sudo su - root -c 'perl -pi -e '...' ...'\""
让我们把单引号中的位替换为废话:
"ssh -t <HOST> \"sudo su - root -c 'AAA'...'BBB'\""
在我看来,perl
不会得到你认为它正在获得的程序,因为你过早地关闭了引号。不是试图在一个字符串中指定所有内容,而是将其构建起来,以便更容易理解转义:
my $perl = q(perl -pi -e \\'...\\');
my $command = qq(sudo su - root -c '$perl');
为什么要在大型系统调用中执行此操作?我现在谈论我自己的工作情况,这种情况是必要的,但我也知道我用Net::SSH::Perl::ProxiedIPC解决了这个问题。它处理所有这些愚蠢的细节。
而且,正如之前对同一问题的回答所指出的那样,sudo
和su
次调用真的很可怕。
答案 1 :(得分:0)
从内到外构建它。
use String::ShellQuote qw( shell_quote );
my $host = 'HOST';
my $path_to_xml = '/home/harrikr/Scripts/TcServerScripts/data.xml';
my $virtualhost1 = 'VIRTUALHOST1';
my $perl_prog = <<'__EOI__';
BEGIN { my $vh = shift(@ARGV); }
s/xmlNamespaceAware="false">\K/<Alias>\Q$vh\E</Alias>/g;
__EOI__
my $perl_cmd = sprintf q{perl -i -pe%s %s %s},
shell_quote($perl_prog),
shell_quote($virtualhost1),
shell_quote($path_to_xml);
my $su_cmd = sprintf q{sudo su - -c%s},
shell_quote($perl_cmd);
my $ssh_cmd = sprintf q{ssh -t %s %s},
shell_quote($host),
shell_quote($su_cmd);
system($ssh_cmd);
你可能会注意到我通过使用\ K regex原子缩短了你的Perl程序。这需要5.10,所以请随意恢复这一变化。
成为root似乎没必要。由于正在编辑的文件似乎属于harrikr
,为什么不简单地将ssh视为该人?我认为这也意味着-t
变得不必要了。
use String::ShellQuote qw( shell_quote );
my $host = 'harrikr@HOST';
my $path_to_xml = '/home/harrikr/Scripts/TcServerScripts/data.xml';
my $virtualhost1 = 'VIRTUALHOST1';
my $perl_prog = <<'__EOI__';
BEGIN { my $vh = shift(@ARGV); }
s/xmlNamespaceAware="false">\K/<Alias>\Q$vh\E</Alias>/g;
__EOI__
my $perl_cmd = sprintf q{perl -i -pe%s %s %s},
shell_quote($perl_prog),
shell_quote($virtualhost1),
shell_quote($path_to_xml);
my $ssh_cmd = sprintf q{ssh %s %s},
shell_quote($host),
shell_quote($perl_cmd);
system($ssh_cmd);