在 R 中不调用 shell 的系统调用

Posted

技术标签:

【中文标题】在 R 中不调用 shell 的系统调用【英文标题】:System call without invoking shell in R 【发布时间】:2015-01-02 04:14:34 【问题描述】:

在基本 R 中,调用系统命令有 3 种主要机制:systemsystem2shell(似乎与 system 共享手册页)。它们都没有提供一种非常可靠的跨平台方式来运行系统命令而没有 shell 的阻碍——如果 shell 介入,我们需要担心 shell 注入攻击,确保引用正确等等.

某些语言提供对 C 级 execvp 函数的直接访问(例如 Perl 的 system PROGRAM LIST 机制),当我想确保数组中的字符串正是子进程将看到的字符串时,这非常有用在其论点中,无需四处寻找嵌入空格、引号等的适当引用例程,也无需担心它们在不同平台和不同版本的 shell 上会做什么。

在 R 中是否有类似的无壳系统调用机制可用,也许在某处的 CRAN 包中?和/或如果还没有这样的机制,是否有兴趣创建这样的机制?

【问题讨论】:

非常有趣的问题,我想知道答案。但是,就目前而言,该问题可能被解释为要求工具(离题)或主要基于意见。我不会投票结束,但也许您可以进行一些编辑来避免这些结果? @Andrie 最后一段的第一个问题还不够吗? @BenBolker - 它不会传递字符串,它会传递字符串的向量(数组),但是是的,在概念上很容易。如果一个已经存在的话,这不是我第一次忽略一个有用的工具。 @Andrie - 如果我更简单地表述为“如何在不调用 shell 的情况下进行系统调用?”它会更好地符合指导方针,但实际上问题是一样的,我只是想提供更多背景信息来说明我的意思以及我想要它的原因。 不,system2 也有同样的问题。如果你看它的源码,它做的第一件事是command <- paste(c(env, shQuote(command), args), collapse = " "),然后它调用了shell。 【参考方案1】:

以下代码在 R 中运行命令,无需 shell 交互:

library(inline)
cfun <- cfunction(sig = signature(),
          includes = "#include <unistd.h>",
body = 'execl("/bin/date", "date", 0, 0, (char *)0);')
cfun()

我很确定这是一个坏主意,因为我认为它会在执行过程完成后终止 R 进程。叉子呢?

基础包并行C函数mc_fork使用C系统命令fork来实现这一点,并带有用于进程间通信的管道。我不知道这将如何在带有 MinGW 的 Windows 上运行,但由于它在一个基本包中,它似乎可以工作,尽管可能有一个非常不同的下游机制。

parallel 的 R 源代码中,我在 R-devel/src/library/parallel/src/fork.c 中看到

SEXP mc_fork(SEXP sEstranged)
...
pid = fork();

【讨论】:

【参考方案2】:

扩展@Jack Wasey 的直觉:

library(inline)
cfun <- cfunction(sig = signature(),
          includes = "#include <unistd.h>",
body = '
pid_t fk = fork();
if (!fk) 
    execl("/bin/date", "date", 0, 0, (char *)0);
 else if (fk == -1) 
    perror("fork");

return(R_NilValue);
')
cfun()

... 使用 fork 来防止当前进程被劫持(至少在 Linux 中是这样),但会安全地将您返回到 R 中,而不会显示任何内容。

【讨论】:

以上是关于在 R 中不调用 shell 的系统调用的主要内容,如果未能解决你的问题,请参考以下文章

socket实现在python中调用操作系统的命令(subprocess)

linux的系统调用和shell命令式一回事吗?请解释下

系统调用在 Atmel AVR Studio(使用 ASF)中不起作用

举例讲解Linux系统下Python调用系统Shell的方法

系统调用

[Linux]系统调用理解