Return Values von Shell Skripten mittels system() erfahren
-
Hallo,
Ich habe folgenden Test gemacht:
#include <cstdlib> #include <iostream> int main() { std::cout << "I got " << system("./testScript test") << std::endl; std::cout << "I got " << system("./testScript") << std::endl; return system("./testScript"); }
Damit rufe ich folgendes Shell-Skript auf:
#!/bin/sh [ ! "$1" ] && echo "kein para" && exit 2 exit 15
Ich wollte testen, ob ich die Rückgabewerte meiner Shell-Skripte in C++ weiterverwenden kann. Das ernüchternde Resultat:
./cppSystemCallTest I got 3840 kein para I got 512 kein para
Es scheint mir, dass ich irgendwelche Phantasie-werte zurück bekomme. Das Skript in der Shell getestet, liefert die richtigen Rückgabewerte! (Kontrolle mit 'echo $?')
Wie führt ihr Skripts/Binarys aus und wertet deren Rückgabewerte aus? System() scheint mir nicht das richtige dafür zu sein.
Danke für Tipps.
-
Du begibst dich hier in plattformabhängiges Gebiet, der C Standard ist ziemlich lax, was den Rückgabewert von system angeht:
C Standard schrieb:
If the argument is a null pointer, the system function returns nonzero only if a
command processor is available. If the argument is not a null pointer, and the system function does return, it returns an implementation-defined value.Die Kunst ist es nun, diesen "implementation-defined value" richtig zu interpretieren. Ich habe dein Programm mal bei mir ausgeführt und habe genau die gleichen Werte herausbekommen, deshalb nehme ich an, dass du ebenfalls ein Linux mit gcc als Compiler einsetzt. Bei dieser Art von System gibt es ein Makro WEXITSTATUS in sys/wait.h. Der Einfachheit halber ist das aber auch schon in cstdlib definiert, du musst also nichts zusätzlich inkludieren. Das Makro nimmt den Rückgabewert von system und gibt dir den exit-code zurück. Das Makro erwartet jedoch einen lvalue als Argument, weswegen du das ergebnis erstmal zwischenspeichern musst:
#include <cstdlib> #include <iostream> int main() { int i = system("./ttestScript test"); std::cout << "I got " << WEXITSTATUS(i) << std::endl; i = system("./testScript"); std::cout << "I got " << WEXITSTATUS(i) << std::endl; i = system("./testScript"); return WEXITSTATUS(i); }
Ausgabe:
I got 15 kein para I got 2 kein para
-
SeppJ schrieb:
Die Kunst ist es nun, diesen "implementation-defined value" richtig zu interpretieren. Ich habe dein Programm mal bei mir ausgeführt und habe genau die gleichen Werte herausbekommen, deshalb nehme ich an, dass du ebenfalls ein Linux mit gcc als Compiler einsetzt. Bei dieser Art von System gibt es ein Makro WEXITSTATUS in sys/wait.h. Der Einfachheit halber ist das aber auch schon in cstdlib definiert, du musst also nichts zusätzlich inkludieren. Das Makro nimmt den Rückgabewert von system und gibt dir den exit-code zurück. Das Makro erwartet jedoch einen lvalue als Argument, weswegen du das ergebnis erstmal zwischenspeichern musst:
Danke SeppJ. Genau auf Grund solcher Antworten, wie deiner jetzt, lerne ich hier so viel!! Ich habe die entsprechenden Hinweise im Man überlesen.
Auf Linux wird nur das höhere Byte des Rückgabewert interpretiert.
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */ #define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum Linux/Unix verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.