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?
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.)
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("\\\\")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With