Это работает для меня в BASH:
sub escape_shell_param($) {
my ($par) = @_;
$par =~ s/'/'"'"'/g; # "escape" all single quotes
return "'$par'"; # single-quote entire string
}
Он основан на следующих утверждениях, взятых из справочной страницы BASH:
- Заключение символов в одинарные кавычки сохраняет буквальное значение каждого символа в кавычках.
- Одиночная кавычка может отсутствовать между одинарными кавычками, даже если ей предшествует обратный слеш.
- Заключение символов в двойные кавычки сохраняет буквальное значение всех символов в кавычках, за исключением $, `,
\, и, когда расширение истории включено,!.
Из (2.) мы знаем, что обратный слеш не может использоваться для экранирования одинарных кавычек, но из (3.) подразумевается, что двойные кавычки сохраняют буквальное значение (иначе говоря, экранирование) одинарных кавычек.
Также обратите внимание, что единственной целью кавычек является изменение значения символов в кавычках (не создаются специальные строковые объекты или подобные объекты), и после раскрытия все последовательные буквенные символы объединяются. Тогда 'foo''bar'
совпадает с foobar
.
То, что делает функция выше, состоит в том, чтобы заключить в кавычки всю строку, чтобы никакой символ в ней не имел специального значения. Однако, чтобы учесть наличие одинарных кавычек, строка разделяется, где бы такие символы не находились, и выполняются следующие операции: предыдущая подстрока завершается ('
), затем вводится одинарная кавычка в двойных кавычках ( "'"
) и начинается следующая подстрока ('
). Вот почему '
глобально заменяется на '"'"'
.
Например (псевдокод):
foo'bar => 'foo' + "'" + 'bar'