Perl-эквивалент PHP-кода

Чтобы избежать строки, которая будет использоваться в качестве аргумента оболочки, мы используем функцию escapeshellarg() в PHP, Есть ли Perl есть эквивалентная функция?

4 ответа

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

как это:

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:

  1. Заключение символов в одинарные кавычки сохраняет буквальное значение каждого символа в кавычках.
  2. Одиночная кавычка может отсутствовать между одинарными кавычками, даже если ей предшествует обратная косая черта.
  3. Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $, `, \ и, когда расширение истории включено,!.

Из (2.) мы знаем, что обратный слеш не может использоваться для экранирования одинарных кавычек, но из (3.) подразумевается, что двойные кавычки сохраняют буквальное значение (иначе говоря, экранирование) одинарных кавычек.

Также обратите внимание, что единственной целью кавычек является изменение значения символов в кавычках (никаких специальных строковых объектов или подобных объектов не создается), и после раскрытия все последовательные литеральные символы объединяются. Затем, 'foo''bar' такой же как foobar,

Функция, приведенная выше, состоит в том, чтобы заключить в кавычки всю строку, чтобы никакой символ в ней не имел специального значения. Однако, чтобы учесть наличие одинарных кавычек, строка разделяется, где бы такие символы не находились, и выполняются следующие операции: предыдущая подстрока завершается ('), затем вводится двойная кавычка ("'") и начинается следующая подстрока ('). Вот почему ' глобально заменен '"'"',

Например (псевдокод):

foo'bar => 'foo' + "'" + 'bar'

Я должен согласиться с @daxim. Но есть некоторые обстоятельства, когда вы не можете использовать это, как передача команды через сокет программе, которая не является perl или не имеет доступного модуля IPC. Я также посмотрел на регулярное выражение, данное @axeman, и это мне кажется немного сложным. Я могу ошибаться, но я думаю, что вам не нужно избегать обратной косой черты в одиночных кавычках для команды. Итак, вы можете просто сделать это:

sub escapeshellarg {
    my $arg = shift;

    $arg =~ s/'/'\\''/g;
    return "'" . $arg . "'";
}

Если у кого-то есть причина, почему это может быть небезопасно, я хотел бы знать. Я протестировал его, используя любые хитрости, которые я мог придумать, чтобы заставить оболочку выполнить произвольный код, но безуспешно, что заставляет меня думать, что это регулярное выражение такое же, как и в реализации PHP.

В реализации PHP говорится, что все, что он делает: добавляет одинарные кавычки вокруг строки и экранирует / экранирует любые существующие одинарные кавычки.

Это единственное, что делает это регулярное выражение. Мысли?

Другие вопросы по тегам