Синтаксис для запуска команды в дочернем процессе и ожидания ее завершения в 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`, ускользает от всех метасимволов