Wie führe ich ein externes Programm in C-Code in Linux mit Argumenten aus?
Lesezeit: 5 Minuten
js0823
Ich möchte ein anderes Programm in C-Code ausführen. Ich möchte zum Beispiel einen Befehl ausführen
./foo 1 2 3
foo ist das Programm, das im selben Ordner vorhanden ist, und 1 2 3 sind Argumente. foo Das Programm erstellt eine Datei, die in meinem Code verwendet wird.
Wie mache ich das?
Warum fragt diese Frage nach C-Code und ist mit C++ gekennzeichnet?
– Johann
9. März 2011 um 16:19 Uhr
Weil jede Lösung in C++ funktionieren würde
– Benutzer9599745
30. Oktober 2019 um 1:27 Uhr
Erik
Verwenden Sie für einen einfachen Weg system():
#include <stdlib.h>
...
int status = system("./foo 1 2 3");
system() wartet, bis foo die Ausführung abgeschlossen hat, und gibt dann eine Statusvariable zurück, mit der Sie z. B. den Exitcode überprüfen können (der Exitcode des Befehls wird mit 256 multipliziert, also teilen Sie den Rückgabewert von system() durch diesen, um den tatsächlichen Exitcode zu erhalten: int exitcode = status / 256).
Die Manpage für wait() (in Abschnitt 2, man 2 wait auf Ihrem Linux-System) listet die verschiedenen Makros auf, mit denen Sie den Status untersuchen können, die interessantesten wären WIFEXITED und WEXITSTATUS.
Alternativ, wenn Sie die Standardausgabe von foo lesen müssen, verwenden Sie popen(3)die einen Dateizeiger zurückgibt (FILE *); Die Interaktion mit der Standard-Ein-/Ausgabe des Befehls entspricht dann dem Lesen oder Schreiben in eine Datei.
@Erik: Was kann ich tun, wenn keine Shell verfügbar ist?
– Benutzer2284570
6. April 2015 um 14:26 Uhr
Diese Lösung ist nicht der richtige Weg, Sie können viele Sicherheitsfehler in Ihre Anwendung einführen. Überprüfen Sie dies: securecoding.cert.org/confluence/pages/… Eine bessere Lösung ist die Verwendung von popen oder execve oder verwandten Funktionen.
– Dunkelmord
30. August 2016 um 12:24 Uhr
Jonathan Ben-Avraham
Das system Funktion ruft eine Shell auf, um den Befehl auszuführen. Das ist zwar bequem, aber bekanntlich Auswirkungen auf die Sicherheit. Wenn Sie den Pfad zu dem Programm oder Skript, das Sie ausführen möchten, vollständig angeben können, können Sie es sich leisten, die Plattformunabhängigkeit zu verlieren system bietet, dann können Sie eine verwenden execve Wrapper wie in der abgebildet exec_prog Funktion unten, um Ihr Programm sicherer auszuführen.
Siehe verwandten SE-Beitrag für Situationen, die eine Kommunikation mit dem ausgeführten Programm über Dateideskriptoren wie z stdin und stdout.
Was macht %s und %m rein machen perror Anrufe) ? Ist es kein Fehler?
– Loxaxe
5. April 2018 um 7:51 Uhr
Pedro Alve
Sie können verwenden fork() und system() damit Ihr Programm nicht bis warten muss system() kehrt zurück.
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[]){
int status;
// By calling fork(), a child process will be created as a exact duplicate of the calling process.
// Search for fork() (maybe "man fork" on Linux) for more information.
if(fork() == 0){
// Child process will return 0 from fork()
printf("I'm the child process.\n");
status = system("my_app");
exit(0);
}else{
// Parent process will return a non-zero value from fork()
printf("I'm the parent.\n");
}
printf("This is my main program and it will continue running and doing anything i want to...\n");
return 0;
}
Es wäre weitaus effizienter, nur execl oder execv aus dem untergeordneten Prozess zu verwenden, da dies keine Shell verwendet, keinen neuen Thread forkt und Sie sowieso direkt nach dem Aufruf von system beenden. Außerdem wird der Prozess zu einem Zombie, wenn Sie wait() nicht aufrufen.
– Billi
26. September 2016 um 21:42 Uhr
Billy
system() führt eine Shell aus, die dann für das Analysieren der Argumente und das Ausführen des gewünschten Programms verantwortlich ist. Um das Programm direkt auszuführen, verwenden Sie fork() und exec() (was system() verwendet, um die Shell auszuführen, sowie das, was die Shell selbst verwendet, um Befehle auszuführen).
#include <unistd.h>
int main() {
if (fork() == 0) {
/*
* fork() returns 0 to the child process
* and the child's PID to the parent.
*/
execl("/path/to/foo", "foo", "arg1", "arg2", "arg3", 0);
/*
* We woundn't still be here if execl() was successful,
* so a non-zero exit value is appropriate.
*/
return 1;
}
return 0;
}
In C
#include <stdlib.h>
system("./foo 1 2 3");
In C++
#include <cstdlib>
std::system("./foo 1 2 3");
Öffnen und lesen Sie die Datei dann wie gewohnt.
Ich versuche dies zu tun, aber anstatt den Wert direkt zu verwenden, muss ich eine AC-Variable übergeben, wie kann ich das tun?
– Everaldo
16. Juli 2021 um 21:37 Uhr
Johann
Wie wäre es so:
char* cmd = "./foo 1 2 3";
system(cmd);
Ich versuche dies zu tun, aber anstatt den Wert direkt zu verwenden, muss ich eine AC-Variable übergeben, wie kann ich das tun?
– Everaldo
16. Juli 2021 um 21:37 Uhr
Hazok
So können Sie auf variable Argumente erweitern, wenn Sie die Argumente nicht fest codiert haben (obwohl sie in diesem Beispiel technisch immer noch fest codiert sind, aber einfach herauszufinden sein sollten, wie sie erweitert werden …):
Warum fragt diese Frage nach C-Code und ist mit C++ gekennzeichnet?
– Johann
9. März 2011 um 16:19 Uhr
Weil jede Lösung in C++ funktionieren würde
– Benutzer9599745
30. Oktober 2019 um 1:27 Uhr