Подстановка текста в файл в скрипте Perl - PullRequest
0 голосов
/ 26 июня 2009

Я использую 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"

Поэтому, если мы хотим изменить имя_сервера на 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 ]

4 голосов
/ 26 июня 2009

Поддержка регулярных выражений в Perl включает в себя операторы \ Q и \ E, которые позволят избежать интерпретации символов регулярных выражений в пределах их области видимости, но они допускают интерполяцию переменных.

Это работает:

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

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

Без \ Q и \ E вы получите ошибку из-за символов регулярного выражения в $i.

0 голосов
/ 26 июня 2009

Самая тривиальная часть - просто прекратить выполнение команды в виде одной строки. Вытащи из него оболочку. Предполагая, что ваша функция 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 $_;
}

Может быть, вы можете сделать то же самое в своем коде? Не уверен, насколько легко это воспроизвести, особенно этот бит $ ^ I. В худшем случае прочитайте файл, запишите новый файл, удалите исходный файл, переименуйте новый файл в исходное имя. Это поможет избавиться от всех опасностей, связанных с прохождением опасного мусора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...