指定在R中使用哪个shell

时间:2016-11-28 13:25:53

标签: r bash shell

我必须在R里面运行一个shell脚本。我考虑过使用R的system函数。

但是,我的脚本涉及source activate以及/ bin / sh shell中没有的其他命令。有没有办法可以使用/ bin / bash代替?

谢谢!

1 个答案:

答案 0 :(得分:6)

调用/bin/bash,并通过-c选项以下列方式之一传递命令:

system(paste("/bin/bash -c", shQuote("Bash commands")))
system2("/bin/bash", args = c("-c", shQuote("Bash commands")))

如果您只想运行Bash 文件,请提供shebang,例如:

#!/bin/bash -
builtin printf %q "/tmp/a b c"

并通过将脚本的路径传递给system函数来调用它:

system("/path/to/script.sh")

暗示当前用户/组有足够的permissions来执行脚本。

原理

之前我建议设置SHELL环境变量。但它可能不会起作用,因为R中system函数的实现调用the C function同名(参见src/main/sysutils.c):

int R_system(const char *command)
{
    /*... */
    res = system(command);

  

system()库函数使用fork(2)创建子进程,该进程使用execl(3)执行命令中指定的shell命令,如下所示:

     

execl("/bin/sh", "sh", "-c", command, (char *) 0);

(请参阅man 3 system

因此,您应该调用/bin/bash,并通过-c选项传递脚本正文。

测试

让我们使用特定于Bash的/tmp列出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

示例输出

/tmp/RtmpjJpuzr
/tmp/fish.ruslan
...

原始答案

尝试设置SHELL环境变量:

Sys.setenv(SHELL = "/bin/bash")
system("command")

然后,应使用指定的shell调用传递给systemsystem2函数的命令。