son - Llamada al sistema sin invocar shell en R
que son las llamadas de sistema (2)
Ampliando la intuición de @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()
... usa un tenedor para evitar el secuestro del proceso actual (al menos en Linux), pero lo devuelve de forma segura a R sin nada que mostrar.
En la base R, hay 3 mecanismos principales para invocar un comando del sistema: system
, system2
y shell
(que parece compartir una página de manual con el system
). Ninguno de ellos proporciona una manera confiable de plataforma cruzada para ejecutar un comando del sistema sin un caparazón en el camino, y si un caparazón interviene, tenemos que preocuparnos por los ataques de inyección del caparazón, por asegurarnos de que las citas sean correctas, etc. .
Algunos lenguajes proporcionan acceso directo a la función execvp
nivel execvp
(por ejemplo, el mecanismo de system PROGRAM LIST
execvp
Perl), que es extremadamente útil cuando quiero asegurarme de que las cadenas de una matriz son exactamente las cadenas que el subproceso verá en sus argumentos, sin buscando la rutina de cotización apropiada para espacios en blanco incrustados, comillas, etc. y preocupándose por lo que harán en diferentes plataformas y diferentes versiones de shells.
¿Existe un mecanismo de llamada de sistema no shell similar disponible en R, tal vez en un paquete CRAN en alguna parte? ¿Y hay algún apetito por crear tal mecanismo si ya no hay uno?
El siguiente código ejecuta un comando en R sin interacción de shell:
library(inline)
cfun <- cfunction(sig = signature(),
includes = "#include <unistd.h>",
body = ''execl("/bin/date", "date", 0, 0, (char *)0);'')
cfun()
Estoy bastante seguro de que esta es una mala idea, ya que creo que terminaría el proceso R una vez que se haya completado el proceso. ¿Qué hay de tenedor?
La función C en paralelo del paquete base mc_fork
usa la fork
comando del sistema C para lograr esto, con tuberías para la comunicación entre procesos. No sé cómo funcionaría esto en Windows con MinGW, pero dado que está en un paquete base, parece probable que funcione, aunque tal vez con un mecanismo descendente muy diferente.
En las fuentes R para parallel
, veo en R-devel/src/library/parallel/src/fork.c
SEXP mc_fork(SEXP sEstranged)
...
pid = fork();