在Perl脚本中替换文件中的文本

时间:2009-06-26 08:51:21

标签: perl sed

我正在使用webmin,我正在尝试更改文件中的某些设置。如果这个人使用任何可能使用以下代码绊倒sed或Perl的奇怪字符,我会遇到问题:

&execute_command("sed -i 's/^$Pref.*\$/$Pref \"$in{$Pref}\"/g' $DIR/pserver.prefs.cache");

其中execute_command是一个webmin函数,基本上可以运行一个特殊的系统调用。 $pref是首选项名称,例如“SERVERNAME”,“OPTION2”等,$in{Pref}将成为我想为PREF设置的选项。例如,这是一个典型的pserver.prefs

SERVERNAME "Test Name"
OWNERPASSWORD "Hd8sdH&3"

因此,如果我们想将SERVERNAME更改为 Tes“t#& ^”@“”@@& 和OWNERPASSWORD为 * @(&'“@ $ “(')29 然后它们将作为$in{Pref}传递。什么是逃避$in{}变量的最简单方法,以便它们可以与sed一起工作,或者更好的是,什么是一种我可以将我的sed命令转换为严格的Perl命令以便它没有错误的方法吗?

更新

太棒了,现在我只想尝试使用它,我收到了这个错误:

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

这不起作用:

my $Pref = "&*())(*&'''''^%$#@!"; 
&execute_command("perl -pi -e 's/^SERVERNAME.*\$/SERVERNAME \"\Q$Pref\E\"/g' $DIR/pserver.prefs");

这样做:

my $Pref = "&*())(*&^%$#@!"; 
&execute_command("perl -pi -e 's/^SERVERNAME.*\$/SERVERNAME \"\Q$Pref\E\"/g' $DIR/pserver.prefs");

2 个答案:

答案 0 :(得分:4)

Perl的正则表达式支持包括\ Q和\ E运算符,这将导致它避免在其范围内解释正则表达式符号,但它们允许变量插值。

这有效:

$i = '(*&%)*$£(*';

if ($i =~ /\Q$i\E/){
    print "matches!\n";
}

如果没有\ Q和\ E,由于$i中的正则表达式符号,您会收到错误。

答案 1 :(得分:0)

最简单的部分就是停止将命令作为单个字符串执行。从中获取外壳。假设您的execute_command函数只是调用系统,请尝试:

execute_command(qw/perl -pi -e/, 's/^SERVERNAME.*$/SERVERNAME "\Q$Pref\E"/g', "$DIR/pserver.prefs");

那更好,但并不完美。毕竟,用户可能会输入一些像“@ [system qw:rm -rf /:]”这样愚蠢的东西然后会发生愚蠢的事情。我认为也有解决方法,但最简单的可能就是简单地在代码中完成工作。怎么做?也许从perl使用“-pi”标志开始可能会有所帮助。我们来看看:

$  perl -MO=Deparse -pi -e 's/^SERVERNAME.*$/SERVERNAME "\Qfoo\E"/'
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    s/^SERVERNAME.*$/SERVERNAME "foo"/;
}
continue {
    print $_;
}

也许你可以在你的代码中做同样的事情?不确定复制有多容易,特别是那个$ ^我有点。最糟糕的情况是,读取文件,写入新文件,删除原始文件,将新文件重命名为原始名称。这将有助于摆脱所有传递危险垃圾的风险。