在 R 中不调用 shell 的系统调用
Posted
技术标签:
【中文标题】在 R 中不调用 shell 的系统调用【英文标题】:System call without invoking shell in R 【发布时间】:2015-01-02 04:14:34 【问题描述】:在基本 R 中,调用系统命令有 3 种主要机制:system
、system2
和 shell
(似乎与 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)
系统调用在 Atmel AVR Studio(使用 ASF)中不起作用