2014-11-05 9 views
35

Nella base R, esistono 3 meccanismi principali per richiamare un comando di sistema: system, system2 e shell (che sembra condividere una manpage con system). Nessuno di questi fornisce un modo cross-platform molto affidabile per eseguire un comando di sistema senza che una shell interferisca - e se interviene una shell, dobbiamo preoccuparci degli attacchi di shell injection, assicurarsi che il quoting sia corretto, e così via .Chiamata di sistema senza richiamare la shell in R

Alcune lingue forniscono l'accesso diretto alla funzione di livello C execvp (ad es. Il meccanismo di Perl system PROGRAM LIST), che è estremamente utile quando voglio assicurarmi che le stringhe in un array siano esattamente le stringhe che il sottoprocesso vedrà nei suoi argomenti , senza cercare la routine di quotazione appropriata per spazi bianchi incorporati, preventivi, ecc. e preoccuparsi di cosa faranno su piattaforme diverse e diverse versioni di shell.

C'è un meccanismo di chiamata di sistema no shell simile disponibile in R, forse in un pacchetto CRAN da qualche parte? E/o c'è qualche appetito per la creazione di un tale meccanismo se non ce n'è uno già?

+0

Domanda molto interessante, e mi piacerebbe sapere la risposta. Tuttavia, così com'è, la domanda può essere interpretata come richiesta di uno strumento (fuori tema) o principalmente basata sull'opinione pubblica. Non voterò per chiudere, ma forse puoi applicare un po 'di editing per evitare questi risultati? – Andrie

+0

@Andrie non è la prima domanda nell'ultimo paragrafo abbastanza? –

+0

@PauloCardoso, come fa notare Andrie, la prima domanda nell'ultimo paragrafo * è * "chiedere uno strumento". Immagino che sarebbe facile scrivere un pacchetto con un pezzo di codice banale che ha appena passato una stringa a 'execvp' ... –

risposta

1

Il seguente codice esegue un comando in R senza interazione guscio:

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

Sono abbastanza sicuro che questa è una cattiva idea, in quanto penso che sarebbe terminare il processo di R al completamento del processo di esecuzione. Che mi dici della forcella?

Il pacchetto base C parallelo mc_fork utilizza il comando di sistema C fork per ottenere questo risultato, con tubi per la comunicazione tra processi. Non so come possa volare su Windows con MinGW, ma dal momento che si trova in un pacchetto base, probabilmente funzionerebbe, anche se forse con un meccanismo downstream molto diverso.

Nelle fonti R per parallel mi vedono in R-devel/src/library/parallel/src/fork.c

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

Ampliando intuizione @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 forchetta per evitare il dirottamento del processo corrente (A almeno in Linux), ma ti riporta in sicurezza a R senza niente da mostrare.