简体   繁体   English

指定在R中使用哪个shell

[英]Specify which shell to use in R

I have to run a shell script inside R. I've considered using R's system function. 我必须在R内运行shell脚本。我已经考虑过使用R的system功能。

However, my script involves source activate and other commands that are not available in /bin/sh shell. 但是,我的脚本涉及到/ bin / sh shell中不可用的source activate和其他命令。 Is there a way I can use /bin/bash instead? 有没有办法可以使用/ bin / bash代替?

Thanks! 谢谢!

Invoke /bin/bash , and pass the commands via -c option in one of the following ways: 调用/bin/bash ,并以下列方式之一通过-c选项传递命令:

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 , eg: 如果您只想运行Bash 文件 ,请为其提供shebang ,例如:

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

and call it by passing script's path to the system function: 并通过将脚本的路径传递给system函数来调用它:

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

It is implied that the current user/group has sufficient permissions to execute the script. 暗示当前用户/组具有执行脚本的足够权限

Rationale 基本原理

Previously I suggested to set the SHELL environment variable. 以前,我建议设置SHELL环境变量。 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 ): 但这可能行不通,因为R中的system功能实现使用相同的名称调用C功能 (请参阅src/main/sysutils.c ):

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

And

The system() library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3) as follows: system()库函数使用fork(2)创建一个子进程,该子进程使用execl(3)执行命令中指定的shell命令,如下所示:

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

(see man 3 system ) (请参阅man 3 system

Thus, you should invoke /bin/bash , and pass the script body via the -c option. 因此,您应该调用/bin/bash ,并通过-c选项传递脚本主体。

Testing 测试中

Let's list the top-level directories in /tmp using the Bash-specific mapfile : 让我们使用特定于Bash的mapfile列出/tmp中的顶级目录:

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 test.sh

Rscript test.R && cat /tmp/out

Sample Output 样本输出

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

Original Answer 原始答案

Try to set the SHELL environment variable: 尝试设置SHELL环境变量:

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

Then the commands passed to system or system2 functions should be invoked using the specified shell. 然后,应使用指定的shell调用传递给systemsystem2函数的命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM