Come eseguire uno script di shell da C in Linux?

Come posso eseguire uno script di shell da C in Linux?

Dipende da cosa vuoi fare con lo script (o qualsiasi altro programma che vuoi eseguire).

Se vuoi solo eseguire il system script è la cosa più semplice da fare, ma fa anche altre cose, inclusa l’esecuzione di una shell e l’esecuzione del comando (/ bin / sh nella maggior parte * nix).

Se vuoi alimentare lo script della shell tramite il suo input standard o consumare il suo output standard, puoi usare popen (e pclose ) per impostare un pipe. Questo usa anche la shell (/ bin / sh nella maggior parte * nix) per eseguire il comando.

Entrambe sono funzioni di libreria che fanno molto sotto il cofano, ma se non soddisfano le tue esigenze (o vuoi solo sperimentare e apprendere) puoi anche utilizzare le chiamate di sistema direttamente. Ciò consente anche di evitare di avere la shell (/ bin / sh) che esegue il comando per te.

Le chiamate di sistema di interesse sono fork , execve e waitpid . Si consiglia di utilizzare uno dei wrapper di libreria su execve (digitare man 3 exec per un elenco di essi). Potresti anche voler utilizzare una delle altre funzioni di attesa ( man 2 wait ha tutte). Inoltre potresti essere interessato alle chiamate di sistema clone e vfork relative alla fork.

fork duplica il programma corrente, in cui l’unica differenza principale è che il nuovo processo ottiene 0 restituito dalla chiamata al fork. Il processo genitore ottiene l’id di processo del nuovo processo (o un errore) restituito.

execve sostituisce il programma corrente con un nuovo programma (mantenendo lo stesso id di processo).

waitpid viene utilizzato da un processo padre per attendere il completamento di un particolare processo figlio.

Avere i passi fork ed execve separati consente ai programmi di eseguire alcune impostazioni per il nuovo processo prima che venga creato (senza fare confusione). Questi includono la modifica di input, output e stderr standard in file diversi rispetto al processo principale utilizzato, la modifica dell’utente o del gruppo del processo, la chiusura di file di cui il bambino non ha bisogno, la modifica della sessione o la modifica delle variabili ambientali.

Potresti anche essere interessato alle chiamate di sistema pipe e dup2 . pipe crea una pipe (con sia un descrittore di file di input che di output). dup2 duplica un descrittore di file come descrittore di file specifico ( dup è simile ma duplica un descrittore di file al descrittore di file disponibile più basso).

Puoi usare il system :

 system("/usr/local/bin/foo.sh"); 

Questo si bloccherà mentre lo si esegue usando sh -c , quindi restituirà il codice di stato.

Se stai bene con POSIX, puoi anche usare popen() / pclose()

 #include  #include  int main(void) { /* ls -al | grep '^d' */ FILE *pp; pp = popen("ls -al", "r"); if (pp != NULL) { while (1) { char *line; char buf[1000]; line = fgets(buf, sizeof buf, pp); if (line == NULL) break; if (line[0] == 'd') printf("%s", line); /* line includes '\n' */ } pclose(pp); } return 0; } 

Un modo semplice è …..

 #include  #include  #define SHELLSCRIPT "\ #/bin/bash \n\ echo \"hello\" \n\ echo \"how are you\" \n\ echo \"today\" \n\ " /*Also you can write using char array without using MACRO*/ /*You can do split it with many strings finally concatenate and send to the system(concatenated_string); */ int main() { puts("Will execute sh with the following script :"); puts(SHELLSCRIPT); puts("Starting now:"); system(SHELLSCRIPT); //it will run the script inside the c code. return 0; } 

Dì grazie a
Yoda @ http://www.unix.com/programming/216190-putting-bash-script-c-program.html

Se hai bisogno di un controllo più preciso, puoi anche utilizzare il percorso exec della fork . Ciò consentirà alla tua applicazione di recuperare i dati emessi dallo script della shell.

Preferisco fork + execlp per il controllo “più fine-grade” come menzionato da Doron. Codice di esempio mostrato di seguito.

Memorizza il comando in un parametro dell’array char e lo spazio malloc per il risultato.

 int fd[2]; pipe(fd); if ( (childpid = fork() ) == -1){ fprintf(stderr, "FORK failed"); return 1; } else if( childpid == 0) { close(1); dup2(fd[1], 1); close(fd[0]); execlp("/bin/sh","/bin/sh","-c",parameters,NULL); } wait(NULL); read(fd[0], result, RESULT_SIZE); printf("%s\n",result);