Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing Perl from R - perlQuote/shQuote?

Tags:

r

perl

I'm trying to run some Perl from R using system: simply assigning a string (provided in R) to a variable and echoing it. (the system call executes in /bin/sh)

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')

However, if I try to echo a backslash (or indeed any string ending in a backslash), I get an error:

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

(Note: the backslash in front of the $ is fine as this protects /bin/sh from thinking $str is a shell variable).

The error is because Perl is interpreting the last \' as an embedded quote mark within $str as opposed to an escaped backslash. In fact, to get perl to echo a backslash I need to do

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

That is, I need to escape my backslashes for Perl (in addition to me escaping them in R/bash).

How can I ensure in echo that the string the user enters is the string that gets printed? i.e. the only level of escaping that is needed is on the R level?

i.e. is there some sort of perlQuote function analagous to shQuote? Should I just manually escape all backslashes in my echo function? Are there any other characters I need to escape given?

like image 218
mathematical.coffee Avatar asked Jan 14 '23 08:01

mathematical.coffee


2 Answers

Don't generate code. That's hard. Instead, pass the argument as an argument:

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

(You could also use an environment variable.)

(I've never used or even seen R code before, so pardon any syntax errors.)

like image 187
ikegami Avatar answered Jan 22 '23 10:01

ikegami


The following seems to work. In Perl, I use q// instead of quotes to avoid problems with the shell quotes.

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("\\\\")
like image 21
Vincent Zoonekynd Avatar answered Jan 22 '23 12:01

Vincent Zoonekynd