2012-03-25 5 views
0

Kann ein Programm in C ein Bashscript generieren und einige Argumente aus dem C-Programm verwenden, um Argumente zum Ausführen des Bashscript im Hintergrundmodus zu parsen (ohne dass der Benutzer merkt, dass wirklich Underground nicht möglich ist), kann ich einige "coole" Funktionen verwenden von Bashscript, um etwas in "C" zu machen? I benötigen das Ergebnis von Bashscript zurück zum C-Programm.Kann ein Programm in C ein Bashscript im Hintergrund erzeugen und aufrufen und Argumente parsen?

Danke in jedem Ratschlag.

+0

Wenn mehr Informationen benötigt werden, fragen Sie danach. –

+0

oh, und wie auch immer, das ist ein cooles Tool-Projekt. –

+0

und perfekt zu sein, ja, ich brauche die Ergebnisse von Bashscript zurück zu C-Programm ... = D –

Antwort

1

Der Befehl system() kann den Job ausführen, wenn Sie den Parameter & für den Scipt-Prozess angeben.

Das Argument der system() sollte der Befehl sein, den Sie ausführen möchten, so als ob Sie es von Bash ausgeführt haben. In diesem Fall wäre es script.sh &, wobei das & dem Betriebssystem mitteilt, den Prozess im Hintergrund auszuführen.

Beachten Sie, dass die Verwendung von system vom Betriebssystem abhängig ist und unsicher sein kann, verwenden Sie sie entsprechend.

1

Haben Sie sich die exec Funktion und Varianten angesehen? Im Grunde ersetzt es den aktuellen Prozess durch einen anderen, je nachdem, was Sie liefern. Ich schlage vor, die Manpages zu lesen, da über diese Funktionen einiges zu wissen ist. Aber ich denke, das ist, was Sie suchen

+0

'exec()' erstellt keinen anderen Prozess. Es ersetzt den aktuellen Prozess. – FatalError

+0

Mein Fehler, es ist bearbeitet – ksol

1

Die Standard-Bibliothek System() Funktion kann helfen. Ein Beispiel könnte wie folgt aussehen:

#include <stdlib.h> 

int main(void){ 
    int scriptResult; 
    scriptResult = system("myscript.sh"); 
    return 0; 
} 

Es gibt wahrscheinlich bessere, tragbare Lösungen für Ihr Problem, aber weil the behavior changes from platform to platform.

+0

Was ist mit Parsen der Argumente? Es ist möglich hier? –

+0

_Nachdem die Befehlsausführung beendet wurde, gibt der Prozessor die Kontrolle an das Programm zurück und gibt einen int Wert zurück, dessen Interpretation systemabhängig ist. _ Hmm .. Wie ich vermutet habe, geht das Loch des weißen Hasen weit nach unten .. –

2

Verwenden fork() einen ‚Klon‘ zu schaffen, die Sie verarbeiten.

Wenn Sie die Ergebnisse von bash (oder was auch immer andere Befehl Sie exec) verwenden pipe() und dup() eine Verbindung zwischen den Prozessen von der Standardausgabe zu erstellen (und Standardfehler, wenn Sie das auch möchten) des exec'd Befehl . Ihr Prozess wird lesen können (und schreiben, wenn Sie mehr Pipes erstellen) exec'd Programme ausgegebenen Text.

Normalerweise verwendet der Klonprozess entweder dup(), um die Standardeingabe/-ausgabe/Fehler auf Pipes wiederherzustellen, oder schließt standardmäßige Standardeingabe/-ausgabe/Fehler, um zu verhindern, dass das Executed-Programm mit dem Benutzer interagiert.

Verwenden Sie dann eine der Formen exec().

Wenn Sie Prozess ist nichtwait() wird der Exec-Prozess 'im Hintergrund' laufen, eigentlich gleichzeitig. Der Effekt, im Hintergrund zu sein, ist hauptsächlich das Ergebnis der Trennung vom Terminal (Tastatur und Fenster).

Wenn die Pipes korrekt eingerichtet sind, kann Ihr Programm mit dem fork + exec'd-Prozess sprechen, aber es ist leicht, eine Dead-Lock-Funktion zu erhalten. Daher schlage ich vor, dass Sie sich darauf beschränken, die Ausgabe zu lesen.

+0

Sintatic, sehr nette Antwort! –

+1

Sie sollten Lernprogramme im Internet finden, die die Namen dieser Systemaufrufe und diesen grundlegenden Ablauf verwenden. Ich habe dies in den 80ern auf UNIX gelehrt, und es gab Papiere und Bücher, die vollständige Antworten gaben. – gbulmer

0

Arbeitsbeispiel unter Linux. change/bin/bash zu Ihrem eigenen Bash-Ort

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <signal.h> 
#include <assert.h> 
#include <sys/wait.h> 

int plumbing(const char * work, char * results, size_t so_results) { 
     int p1[2],p2[2]; 
     pid_t pid,pidw; 
     void (*old)(int); 
     int bytes,cnt,status,rc; 
     char * bash[2] = {"/bin/bash",0}; 
     old=signal(SIGCHLD,SIG_DFL); 
     rc = pipe(p1); if(rc){perror("pipe()");return -1;} 
     rc = pipe(p2); if(rc){perror("pipe()");return -1;} 
     pid = fork(); 
     if (pid<0) { perror("fork"); return -1;} 
     if (0 == pid) { 
       rc = dup2(p1[0],0); if (-1 == rc) {perror("dup2"); return -1;} 
       rc = dup2(p2[1],1); if (-1 == rc) {perror("dup2"); return -1;} 
       close(p1[1]); close(p2[0]); 
       rc = execvp(bash[0],bash); 
       if (-1 == rc) {perror("execvp"); return -1;} exit(-1); 
     } 
     close(p1[0]);close(p2[1]); 
     write(p1[1],work,strlen(work)); 
     cnt = 0; 
     close(p1[1]); 
     bytes = read(p2[0],results,so_results); 
     while(bytes > 0) { 
       cnt+=bytes; 
       if (so_results== cnt) break; 
       bytes = read(p2[0],results+cnt,so_results-cnt); 
     } 
     if (cnt == so_results) { 
       char dummy[4096]; 
       bytes = read(p2[0],dummy,4096); 
       while (bytes>0) { 
         bytes = read(p2[0],dummy,4096); 
       } 
     } 
     pidw = waitpid(pid,&status,WCONTINUED|WUNTRACED); 
     if (pidw != pid || status !=0) { perror("waitpid"); return -1;} 
     signal(SIGCHLD,old); 
     return 0; 
} 
int main() { 
     int rc; 
     char buffer[4096]; 
     rc = plumbing(
"t=$(cat<< @@@\n" 
"ICAgICAgIGE4ODg4Yi4KICAgICAgZDg4ODg4OGIuCiAgICAgIDhQIllQIlk4OAogICAgICA4fG98fG98\n" 
"ODgKICAgICAgOCcgICAgLjg4CiAgICAgIDhgLl8uJyBZOC4KICAgICBkLyAgICAgIGA4Yi4KICAgIGRQ\n" 
"ICAgLiAgICBZOGIuCiAgIGQ4OicgICIgIGA6Ojg4YgogIGQ4IiAgICAgICAgICdZODhiCiA6OFAgICAg\n" 
"JyAgICAgIDo4ODgKICA4YS4gICA6ICAgICBfYTg4UAouXy8iWWFhXzogICAufCA4OFB8ClwgICAgWVAi\n" 
"ICAgIGB8IDhQICBgLgovICAgICBcLl9fXy5kfCAgICAuJwpgLS0uLl9fKTg4ODhQYC5fLicK\n" 
"@@@)\n" 
"r64=\'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/\'\n" 
"i=0; while [ $i -lt 256 ] ; do tab[$i]=-1 ; let i=$i+1 ;done\n" 
"i=0; while [ $i -lt 64 ] ; do tab[`printf \"%d\" \"\'${r64:$i:1}\"`]=$i ; let i=$i+1; done\n" 
"bi=0\n" 
"i=0 \n" 
"while ((i < ${#t})) \n" 
" do\n" 
" x=${t:$i:1}\n" 
" in=${tab[`printf \"%d\" \"\'$x\"`]}\n" 
" if [ $in -ge 0 ]; then case $bi in\n" 
" 0) out=$(($in<<2)); bi=6 ;;\n" 
" 2) out=$(($out|$in)); printf \\\\$(printf \'%03o\' $(($out&255))); bi=0 ;;\n" 
" 4) out=$(($out+($in>>2))); printf \\\\$(printf \'%03o\' $(($out&255)));\n" 
" bi=0; out=$(($in<<6)); bi=2 ;;\n" 
" *) out=$(($out+($in>>4))); printf \\\\$(printf \'%03o\' $(($out&255)));\n" 
" bi=0; out=$(($in<<4)); bi=4 ;;\n" 
" esac fi\n" 
" i=$((1+$i))\n" 
" done\n" 
     ,buffer,4096); 
     printf("plumbing rc %d\n",rc); 
     printf("%s", buffer); 
} 
+0

Wenn Sie mehr Argumente an bash übergeben möchten, zum Beispiel bash -o xtrace, können Sie die Array-Deklaration von char * bash [2] = {"/ bin/bash", 0} ändern; zu char * bash [4] = {"/ bin/bash", "-o", "xtrace", 0}; – pizza

Verwandte Themen