我必须在R里面运行一个shell脚本。我考虑过使用R的system
函数。
但是,我的脚本涉及source activate
以及/ bin / sh shell中没有的其他命令。有没有办法可以使用/ bin / bash代替?
谢谢!
答案 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调用传递给system
或system2
函数的命令。