Чтобы избежать строки, используемой в качестве аргумента оболочки, мы используем функцию escapeshellarg()
в PHP
. Имеет ли Perl
эквивалентную функцию?
String::ShellQuote
, но большую часть времени это не требуется. Вы просто можете избежать вызова оболочки путем тщательного программирования. Например, system
принимает список аргументов вместо строки.
Наилучшая практика:
use IPC::System::Simple qw(systemx); systemx($command, @arguments);
require IPC::System::Simple; use autodie qw(:all); system([@allowed_exit_values], $command, @arguments);
Perl может соответствовать следующей заявленной функции:
добавляет одинарные кавычки вокруг строки и кавычки / экранирует любые существующие одинарные кавычки
http://php.net/manual/en/function.escapeshellarg.php#function.escapeshellarg
как это:
sub php_escapeshellarg { my $str = @_ ? shift : $_; $str =~ s/((?:^|[^\\])(?:\\\\)*)'/$1'\\''/g; return "'$str'"; }
Это работает для меня в BASH:
sub escape_shell_param($) { my ($par) = @_; $par =~ s/'/'"'"'/g; # "escape" all single quotes return "'$par'"; # single-quote entire string }
Он основан на следующих утверждениях, взятых на странице управления BASH:
- Вложения символов в одинарных кавычках сохраняют буквальное значение каждого символа в кавычках.
- Одинарная кавычка может отсутствовать между одинарными кавычками, даже если ей предшествует обратная косая черта.
- Закрывающиеся символы в двойных кавычках сохраняют буквальное значение всех символов внутри кавычек, за исключением $, `, \, и, когда включено расширение истории,!.
Из (2.) мы знаем, что обратная косая черта не может использоваться для выхода из одиночных qoutes, но из (3.) подразумевается, что двойные кавычки сохраняют буквальное значение (aka escape) одиночных кавычек.
Также обратите внимание, что единственной целью кавычек является изменение значения цитируемых символов (не создаются специальные строковые объекты или подобные вещи), и после расширения все последовательные литералы объединяются вместе. Затем 'foo''bar'
совпадает с foobar
.
То, что делает вышеприведенная функция, – это одинарная кавычка всей строки, так что в ней нет специального символа. Однако, чтобы допускать присутствие символов одиночной кавычки, строка разбивается везде, где такие символы найдены, и выполняются следующие операции: предыдущая подстрока завершена ( '
), затем вводится двойная кавычка ( "'"
), а следующая подстрока запускается ( '
). Вот почему '
глобально заменяется на '"'"'
.
Например (псевдокод):
foo'bar => 'foo' + "'" + 'bar'
Я должен согласиться с @daxim. Но есть некоторые обстоятельства, при которых вы не можете использовать это, например, передавать команду через сокет в программу, которая не является perl или не имеет доступного модуля IPC. Я также посмотрел на регулярное выражение, данное @axeman, и это кажется мне немного сложным. Я мог ошибаться, но я думаю, что вам не нужно скрывать обратную косую черту в одиночных кавычках для команды. Итак, вы могли бы просто сделать это:
sub escapeshellarg { my $arg = shift; $arg =~ s/'/'\\''/g; return "'" . $arg . "'"; }
Если у кого-то есть причина, почему это может быть небезопасно, я хотел бы знать. Я протестировал его с помощью любого трюка, о котором я мог подумать, чтобы заставить оболочку выполнить произвольный код без успеха, что заставляет меня думать, что это регулярное выражение такое же, как и реализация PHP.
В реализации PHP он утверждает, что все, что он делает: добавляет одинарные кавычки вокруг строки и кавычки / экранирует любые существующие одинарные кавычки.
Это единственное, что делает это регулярное выражение. Мысли?