ich starte über ein c++ programm ein weiteres programm. dieses gestartete programm gibt fleissig output in die konsole. diesen output würde ich nun gerne in meinem programm als string verarbeiten. welche möglichkeiten habe ich, den fremden konsolenouptut aufzufangen?
Es gibt zum Einen die Möglichkeit, das Programm mit popen() zu starten. Damit kann man wahlweise die Ein- oder die Ausgabe umleiten. Eine andere Variante, mit der beides gleichzeitig geht (und vermutlich auch gleich stderr) ist es, das Programm mit system() zu starten. In der dort anzugebenden Kommandozeile kann man nach dem Programmaufruf die Ein- und Ausgabe mit "... >&95 <&97" mit Dateien verknüpfen, die im aufrufenden Prozeß die fd-Nummern beispielsweise 95 und 97 haben. Man öffnet also vorher die Dateien und trägt die fd-Nummern mit sprintf() in die Kommandozeile ein. Analog z.B. "... 2>&98 ..." für stderr (was mal unter Windows 2000 bei mir geklappt hatte, unter XP irgendwann mal nicht; ich habe es aber nicht weiter verfolgt). Startet man das Programm zusätzlich mit einem & am Ende, kann man während es läuft zu fd 97 etwas schreiben, was vom Kindprozeß von stdin gelesen wird, und gleichzeitig von 95 bzw. 98 dessen Ausgabe lesen. Dieser Weg ist etwas umständlicher, aber wesentlich flexibler. Einfacher ist popen(), wenn es reicht.
Ich gehe mal davon aus, dass du die Möglichkeit hast, den standard output deines Programms abzufangen. In C# gehts über die Klasse Process, wenn ich mich nicht irre...
PS: es geht natürlich nur, wenn das Kind Standardein- und -ausgabe verwendet. Die Windows-eigenen Konsolenfunktionen lassen sich so nicht abfangen.
Falls das Programm myprog.exe ist: In der Konsole myprog >Dateiname eingeben. z.B. dir >d.txr
die sache verhält sich im detail folgendermaßen. ich nutze um das programm zu öffnen die pstream lib welche auf popen aufsetzt. (http://pstreams.sourceforge.net/) öffne ich damit als beispiel ifconfig:
1 | std::string s, ausgabe; |
2 | redi::pstream ifconfig("ifconfig -a"); |
3 | while(std::getline(ifconfig, s)) { |
4 | ausgabe.append(s); |
5 | ausgabe.append("\n"); |
6 | }
|
7 | textview_buffer->set_text(ausgabe); |
landet der konsolenoutput wunderbar im string ausgabe und wird meinem gtk widget zugefügt. ich will aber nicht ifconfig anzeigen. mein programm startet ein android sdk tool welches unterschiedliche parameter hat. mit einem der parameter geht es. dieser parameter öffnet eine shell zum android device und ich kann problemlos infos hin und her schieben
1 | std::string s, ausgabe; |
2 | chdir(path_to_adb.c_str()); |
3 | redi::pstream adb_shell("./adb shell"); |
4 | adb_shell << "mount /system" << std::endl; |
5 | adb_shell << "chmod 644 /system/app/*" << std::endl; |
6 | adb_shell << "chmod 644 /system/framework/*" << std::endl; |
7 | adb_shell << "exit" << std::endl; |
8 | while(std::getline(adb_shell, s)) { |
9 | ausgabe.append(s); |
10 | ausgabe.append("\n"); |
11 | }
|
12 | textview_buffer->set_text(ausgabe); |
folgende anweisung geht aber nicht. dieses mal wird keine shell geöffnet sondern durch das android tool der inhalt eines ordners datei für datei gepushed.
1 | std::string s, ausgabe; |
2 | std::string system_app; |
3 | std::string copy_apps; |
4 | system_app = "ls "; |
5 | system_app.append(path_to_binary); |
6 | system_app.append("/system/app/"); |
7 | redi::ipstream ls(system_app); |
8 | while (ls >> copy_apps) { |
9 | chdir(path_to_adb.c_str()); |
10 | std::string command = "./adb push "; |
11 | command.append(path_to_binary); |
12 | command.append("/system/app/"); |
13 | command.append(copy_apps); |
14 | command.append(" /system/app/"); |
15 | redi::pstream adb_push(command); |
16 | while(std::getline(adb_push, s)) { |
17 | ausgabe.append(s); |
18 | ausgabe.append("\n"); |
19 | }
|
20 | |
21 | textview_buffer->set_text(ausgabe); |
22 | }
|
der unterschied zwischen der 2. und 3. anweisung ist eigentlich nur der, das adb shell eine dauerhafte verbindung aufbaut in welche ich schreiben und lesen kann. adb push hält keine verbindung offen. es kopiert die datei und damit ist die sache abgeharkt. aber auch adb push gibt auf der konsole output über die kopierten daten und wie lange es gedauert hat. ich komme halt nur nicht ran.
hier noch mal das letzte listing in übersichtlich und ohne unnötigen schnick schnack
1 | std::string s, ausgabe; |
2 | chdir(path_to_adb.c_str()); |
3 | redi::pstream adb_pull("./adb pull /system/app /home/dir/"); |
4 | while(std::getline(adb_pull, s)) { |
5 | ausgabe.append(s); |
6 | ausgabe.append("\n"); |
7 | }
|
8 | textview_buffer->set_text(ausgabe); |
adb mit dem parameter pull gibt mir also über die pstream lib keinen output zurück. schiebt aber trotzdem output in die konsole.
Du solltest mit etwas einfacherem anfangen! Wie wärs, wenn du dir als erstes Grundkenntnisse im Benutzen der Shift-Taste aneignest? Das übst du dann noch ein wenig, dann kommt der nächste Schritt.
schlechten tag erwischt? sprich dich aus, das hilft dir vielleicht über deinen frust hinweg zu kommen...
Wie glaubst Du den Compiler zur Zusammenarbeit zu ueberreden, wenn Du Dich nicht an dessen Regeln haeltst? Eben, da kannst Du dessen Rechtschreibung beachten. Aber bei uns hier denkst Du, die sollen mir doch bloss helfen, deren Regeln interessieren mich einen Sch.....dreck. Dann interessieren uns Deine Probleme eben noch weniger. Gast
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.