2013-05-19 1 views
4

Я пытаюсь запустить некоторый Perl из R, используя system: просто назначая строку (предоставленную в R) переменной и эхо ее. (system вызов выполняется в /bin/sh)Выполнение Perl из R - perlQuote/shQuote?

echo <- function (string) { 
    cmd <- paste(shQuote(Sys.which('perl')), 
       '-e', 
       shQuote(sprintf("$str=%s; print $str", shQuote(string)))) 
    message(cmd) 
    system(cmd) 
} 
# all fine: 
# echo('hello world!') 
# echo("'") 
# echo('"') 
# echo('foo\nbar') 

Однако, если я пытаюсь echo обратной косой черты (или действительно любой строки, оканчивающиеся на обратной косой черты), я получаю сообщение об ошибке:

> echo('\\') 
'/usr/bin/perl' -e "\$str='\\'; print \$str" 
Can't find string terminator "'" anywhere before EOF at -e line 1. 

(Примечание: обратная косая черта перед $ в порядке, так как это защищает /bin/sh от мышления $str - это переменная оболочки).

Ошибка в том, что Perl интерпретирует последний \' как внедренный кавычки в $str в отличие от сбежавшего обратной косой черты. На самом деле, чтобы получить Perl эхо обратной косой черты, что нужно сделать

> echo('\\\\') 
'/usr/bin/perl' -e "\$str='\\\\'; print \$str" 
\ # <-- prints this 

То есть, мне нужно, чтобы избежать мои обратные слэши для Perl (в дополнение ко мне избежать их в R/Баш).

Как я могу обеспечить в echo, что строка, которую вводит пользователь, является строкой, которая печатается? то есть единственный уровень экранирования, который необходим, находится на уровне R?

i.e есть какая-то функция perlQuote функция аналог до shQuote? Должен ли я просто избегать всех обратных косых черт в моей функции echo? Есть ли другие символы, которые мне нужно избегать?

+0

(Я пытаюсь сделать пакет 'cowsay' для R, чтобы объединиться с пакетом' fortunes', поэтому вопрос для хорошей причины!;)) –

ответ

6

Не генерировать код. Это трудно. Вместо этого, передать аргумент в качестве аргумента: (. Вы можете также использовать переменное окружение)

echo <- function (string) { 
    cmd <- paste(shQuote(Sys.which('perl')), 
       '-e', shQuote('my ($str) = @ARGV; print $str;'), 
       shQuote(string)) 
    message(cmd) 
    system(cmd) 
} 

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

+0

отлично! Я не знал о @ARGV. ура! –

3

Следующие, похоже, работают. В Perl я использую q// вместо кавычек, чтобы избежать проблем с кавычками оболочки.

perlQuote <- function(string) { 
    escaped_string <- gsub("\\\\", "\\\\\\\\", string) 
    escaped_string <- gsub("/", "\\/", escaped_string) 
    paste("q/", escaped_string, "/", sep="") 
} 
echo <- function (string) { 
    cmd <- paste(shQuote(Sys.which('perl')), 
       '-le', 
       shQuote(sprintf("$str=%s; print $str", perlQuote(string)))) 
    message(cmd) 
    system(cmd) 
} 
echo(1) 
echo("'"); echo("''"); echo("'\""); echo("'\"'") 
echo('"'); echo('""'); echo('"\''); echo('"\'"'); 
echo("\\"); echo("\\\\") 
Смежные вопросы