2014-11-05 8 views
35

In der Basis R gibt es drei Hauptmechanismen zum Aufrufen eines Systembefehls: system, system2 und shell (der eine Manpage mit system zu teilen scheint). Keiner von ihnen bietet eine sehr zuverlässige plattformübergreifende Möglichkeit, einen Systembefehl auszuführen, ohne dass eine Shell in die Quere kommt - und wenn eine Shell interveniert, müssen wir uns Gedanken über Shell-Injection-Angriffe machen, sicherstellen, dass das Zitat korrekt ist und so weiter .Systemaufruf ohne Aufruf der Shell in R

Einige Sprachen bieten direkten Zugriff auf die C-Ebene execvp Funktion (zB system PROGRAM LIST Mechanismus Perl), die sehr hilfreich ist, wenn ich sicherstellen möchten, dass die Strings in einem Array sind genau die Saiten der Subprozess in seiner Argumente sehen , ohne nach der passenden Quotierungsroutine für eingebettete Leerzeichen, Zitate usw. Ausschau zu halten und sich Gedanken darüber zu machen, was sie auf verschiedenen Plattformen und in verschiedenen Versionen von Shells tun werden.

Gibt es einen ähnlichen No-Shell System-Mechanismus in R, vielleicht irgendwo in einem CRAN-Paket? Und/oder besteht ein Appetit auf die Schaffung eines solchen Mechanismus, wenn es noch keinen gibt?

+0

Sehr interessante Frage, und ich würde gerne die Antwort wissen. Wie auch immer, die Frage kann möglicherweise so interpretiert werden, dass entweder nach einem Werkzeug gefragt wird (off topic) oder hauptsächlich auf der Meinung von Meinungen. Ich werde nicht abstimmen, um zu schließen, aber vielleicht können Sie etwas Bearbeitung anwenden, um diese Ergebnisse zu vermeiden? – Andrie

+0

@Andrie ist nicht die erste Frage im letzten Absatz genug? –

+0

@PauloCardoso, wie Andrie hervorhebt, ist die erste Frage im letzten Absatz * "nach einem Werkzeug fragen". Ich stelle mir vor, es wäre einfach, ein Paket mit einem trivialen Code zu schreiben, der eine Zeichenfolge an execvp ... –

Antwort

1

Der folgende Code führt einen Befehl in R ohne Interaktion Shell:

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

Ich bin ziemlich sicher, das eine schlechte Idee ist, wie ich denke, es würde den R-Prozess nach Abschluss des ausgeführten Prozesses beenden. Was ist mit Gabel?

Das Basispaket parallele C-Funktion mc_fork verwenden Sie den C-Systembefehl fork, um dies zu erreichen, mit Rohren für die Kommunikation zwischen Prozessen. Ich weiß nicht, wie das unter Windows mit MinGW funktionieren würde, aber da es in einem Basispaket ist, würde es wahrscheinlich funktionieren, obwohl vielleicht mit einem sehr unterschiedlichen Downstream-Mechanismus.

In der R Quellen für parallel sehe ich in R-devel/src/library/parallel/src/fork.c

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

Aufbauend auf @Jack Wasey Intuition:

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() 

... verwendet Gabel die Entführung des aktuellen Prozesses zu verhindern (bei Am wenigsten in Linux), aber bringt Sie sicher zu R zurück mit nichts, um es zu zeigen.