Reputation: 13675
R> system('bash -c "cat <(seq 3)"', intern=T)
[1] "1" "2" "3"
If I use any bash-specific features, I will have to manually call bash -c
. But that means I will have to properly escape it so that it can be embedded in a string. For example, I can manually escape the bash code like this.
R> system('bash -c "cat <(printf \'%s\\n\' {a..c})"', intern=T)
[1] "a" "b" "c"
But how to automate the escape process robustly, so that it will work on arbitrary bash code.
Essentially, I want to have a function that can turn any legal bash command string (e.g., cat <(printf '%s\n' "'" {a..c})
) into a string runable by system()
. Note the requirement of robustness, it must work with any arbitrary legal bash command.
EDIT: It seems that if printf %q
from bash can be implemented in R, this problem may be solved? If so, how to implement it?
Upvotes: 0
Views: 131
Reputation: 11316
To avoid manually inserting escapes in system
commands, you can construct the commands using shQuote
, possibly recursively. shQuote
wraps its argument (a string) in single or double quotes depending on its content, inserting escapes as necessary, and returns the result. sprintf
and paste
are often useful here:
cmd_bash <- sprintf("cat <(printf %s %s %s)", shQuote("%s\n"), shQuote("'"), "{a..c}")
cmd_bash
## [1] "cat <(printf '%s\n' \"'\" {a..c})"
cmd <- paste("bash -c", shQuote(cmd_bash))
cmd
## [1] "bash -c \"cat <(printf '%s\n' \\\"'\\\" {a..c})\""
system(cmd, intern = TRUE)
## [1] "'" "a" "b" "c"
FWIW, you can read from stdin
interactively with readLines
, using ControlD to signal EOF and/or argument n
to signal EOF after n
lines have been entered:
zzz <- readLines(stdin())
## '
## a
## b
## c
## ^D
zzz
## [1] "'" "a" "b" "c"
zzz <- readLines(stdin(), n = 4L)
## '
## a
## b
## c
zzz
## [1] "'" "a" "b" "c"
zzz <- system(paste("bash -c", shQuote(readLines(stdin(), n = 1L))), intern = TRUE)
## cat <(printf '%s\n' "'" {a..c})
zzz
## [1] "'" "a" "b" "c"
In the last example, the Bash command was typed as if at a Bash prompt, in the running R process.
Upvotes: 1