I have to run a shell script inside R. I've considered using R's system
function.
However, my script involves source activate
and other commands that are not available in /bin/sh shell. Is there a way I can use /bin/bash instead?
Thanks!
The shell is a program that presents a command line interface which allows you to control your computer using commands entered with a keyboard instead of controlling graphical user interfaces (GUIs) with a mouse/keyboard combination.
10.2 RStudio In RStudio, commands can be executed from shell scripts by pressing Ctrl + Enter .
🔗 Base system()/system2() R will convert this into the shell command that writes output to a temporary file, such as below. After the command exits with success, R tries to read the file and return the content.
Use Rscript to run R from bash R comes with Rscript , a command line tool that can run R scripts or R commands directly from the bash shell. You can run it using Rscript test. r . And even better, if you add an initial shebang line #!/usr/bin/env Rscript in the script above and make it executable with chmod +x test.
Invoke /bin/bash
, and pass the commands via -c
option in one of the following ways:
system(paste("/bin/bash -c", shQuote("Bash commands")))
system2("/bin/bash", args = c("-c", shQuote("Bash commands")))
If you only want to run a Bash file, supply it with a shebang, e.g.:
#!/bin/bash -
builtin printf %q "/tmp/a b c"
and call it by passing script's path to the system
function:
system("/path/to/script.sh")
It is implied that the current user/group has sufficient permissions to execute the script.
Previously I suggested to set the SHELL
environment variable. But it probably won't work, since the implementation of the system
function in R calls the C function with the same name (see src/main/sysutils.c
):
int R_system(const char *command)
{
/*... */
res = system(command);
And
The
system()
library function usesfork(2)
to create a child process that executes the shell command specified in command usingexecl(3)
as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
(see man 3 system
)
Thus, you should invoke /bin/bash
, and pass the script body via the -c
option.
Let's list the top-level directories in /tmp
using the Bash-specific mapfile
:
test.R
script <- '
mapfile -t dir < <(find /tmp -mindepth 1 -maxdepth 1 -type d)
for d in "${dir[@]}"
do
builtin printf "%s\n" "$d"
done > /tmp/out'
system2("/bin/bash", args = c("-c", shQuote(script)))
test.sh
Rscript test.R && cat /tmp/out
Sample Output
/tmp/RtmpjJpuzr
/tmp/fish.ruslan
...
Try to set the SHELL
environment variable:
Sys.setenv(SHELL = "/bin/bash")
system("command")
Then the commands passed to system
or system2
functions should be invoked using the specified shell.
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