Запустите поиск sed и замените внутри perl - PullRequest
0 голосов
/ 28 июля 2020

Я пытаюсь протестировать приведенный ниже фрагмент кода для написанного мной сценария большего размера. Однако я не могу заставить поиск работать с круглыми скобками и переменными.

Благодарю за любую помощь, которую кто-то может мне дать.

Фрагмент кода:

#!/usr/bin/perl

$file="test4.html";
$Search="Help (Test)";
$Replace="Testing";

print "/usr/bin/sed -i cb 's/$Search/$Replace/g' $file\n";
`/usr/bin/sed -i cb 's/$Search/$Replace/g' $file`;

Спасибо,

А sh

1 Ответ

0 голосов
/ 28 июля 2020

Синтаксис для запуска команды в дочернем процессе и ожидания ее завершения в perl: system "cmd", "arg1", "arg2",...:

#!/usr/bin/perl

$file="test4.html";
$Search="Help (Test)";
$Replace="Testing";

print "/usr/bin/sed -icb -e 's/$Search/$Replace/g' -- $file\n";
system "/usr/bin/sed", "-icb", "-e", "s/$Search/$Replace/g", "--", $file;

(проверка ошибок оставлена ​​как упражнение, подробности см. В perldoc -f system )

Обратите внимание, что -i не является стандартным вариантом sed. Несколько поддерживающих его реализаций (ваша должна быть FreeBSD, поскольку вы отделили расширение резервного копирования cb от -i) фактически скопировали его из perl! Звонить здесь sed из perl кажется немного глупым.

Глядя на ваш подход:

Сам оператор `...` напоминает эквивалентную оболочку `...` оператор. В perl то, что находится внутри, оценивается как внутри двойных кавычек, в этих $var, @var ... perl переменные раскрываются, и оболочка запускается с -c и полученной строкой в ​​качестве аргументов и со своим стандартным выводом, перенаправленным в канал.

Оболочка интерпретирует этот аргумент как код в синтаксисе оболочки. Perl считывает вывод этого встроенного сценария оболочки с другого конца канала, что составляет расширение `...`. То же, что и при подстановке команд оболочки, за исключением того, что нет удаления нулевых байтов или завершающих символов новой строки.

sed -i не выводит ничего, поэтому бессмысленно пытаться захватить его вывод с помощью `...` здесь.

Теперь в вашем случае код, который требуется интерпретировать sh, выглядит следующим образом:

/usr/bin/sed -i cb 's/Help (Test)/Testing/g' test4.html

Это должно нормально работать, по крайней мере, на FreeBSD или macOS. Если бы $file было test$(reboot).html, это было бы хуже.

Здесь, поскольку у вас есть содержимое переменных, которые в конечном итоге интерпретируются как код в интерпретаторе (здесь sh), у вас есть потенциальная уязвимость, связанная с произвольным внедрением команд.

В подходе system мы удаляем sh, чтобы исключить конкретную уязвимость. Однако sed также является интерпретатором некоторого языка. Этот язык не так всемогущ, как язык sh, но, например, sed может записывать в произвольные файлы с помощью своей команды w. Реализация GNU (которую вы, похоже, не используете) также может запускать произвольные команды. внешний источник.

В этом случае вам нужно убедиться, что вы правильно очистили эти значения перед запуском sed. См., Например: Как убедиться, что строка, интерполированная в подстановку `sed`, ускользает от всех метасимволов

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