C : Rückgabe von Shell bei Befehlen ohne Antwort
-
Es ist schwer das problem im Titel richtig zu erklären und hoffe ich kann es hier verständlich schildern.
Ich schreibe ein Frontend für kommandozeilenorientierte programm, um funktionen zu implementieren die bei diesen fehlen. Hierzu habe ich 2 prozesse,
P1 liest usereingaben ein leitet diese an P2 weiter
P2 führt den Befehl aus.beispiel :
im p2 läuft eine shell , p1 senden ls, p2 verarbeit dies p1 gibt das ergebnis aus.Momentan warte ich per select im P1 bis P2 fertig ist, mein Problem ist nun aber das wenn ich einen befehl habe der nichts zurück gibt wie z.b mkdir ich auf der pipe die select überwacht natürlich keine informationen erhalte und der prozess nicht fortgesetzt wird. ( das in p2 eine shell läuft ist nur ein beispiel es könnte auch z.b sqlplus sein )
Mein frage ist, wie kann ich bei einem beliebig in einem gesondert gestarteten prozess überprüfen ob der befehl ausgeführt wurde, wenn :
a) der hauptprozess der den befehl verarbeitet nicht beendet wird
b) u.u keine daten zurück / ausgebeben werden
c) die lösung allg. funktionieren mussHier noch ein Codeausschnitt :
P2 (shell beispeil)
//P2 { // umleitungen per pipes //stdout P1 = stdin P2 // stdout P2 = stdin P1 ...... if(execl("/bin/sh","sh",NULL) == -1){ fprintf(stderr,"execl Error!"); exit(1); } }
Woher weiss ich nun das P2 z.b den befehl chmod ausgeführt hat
$? auszulesen bringt hier leider auch nichts da dies shell spezifisch wäreist ein problem in dieser form überhaupt lösbar ?
-
tallan schrieb:
ist ein problem in dieser form überhaupt lösbar ?
Meines Erachtens nicht so allgemein, dass es sowohl mit einer Shell, als auch mit sqlplus oä. sauber funktioniert.
Was genau ist Dein Ziel? Ich sehe da gerade irgendwie keinen Use-Case und tue mir insofern auch etwas schwer, Alternativen vorzuschlagen.
-
es ist ein vordefinierte aufgabenstellung es geht darum ein frontend zu schreiben das z.b für sh oder sqlplus eine kommandohistory änhlich wie bei der bash realisiert. Bis auf die allg. lösung steht das programm auch soweit,..
für die shell habe ich z.z eine "notlösung" in dem ich nach der usereingabe einfach ein ; echo anhänge, somit funkioniert die verzögerung durch select ( was aber nicht sauber gelöst ist und auch für andere programme nicht funktioniert )individuelle lösungen grade was sh angeht gibt es imo
z.b $? überprüfen oder eben diese echo "" variante.
Eine andere bzw. allgemeine fällt mir leider nicht ein.die frage wäre also ob es ein allgemeines event gibt das nach erfolgreichem abarbeiten eines befehls eintritt...
ich kann ja schlecht die resourcenauslastung des prozesses überwachen, was nebenbei die einzige möglichkeit wäre die mir einfällt
und den einleseprozess schlafen zu schicken wäre nicht das problem aber hierzu bräuchte man eben wieder genau besagtes event um ihn zu wäcken
-
Du musst halt spezifizieren was ausgeführt bedeutet und das geht eben nicht unbedingt auf eine derartige generische Weise, dass es mit unix-shells, sqlshell etc. funktioniert.
Aber heißt ausgeführt für dich, dass du wieder einen Prompt für die nächste Anweisung hast? Das sollte sich einfach überprüfen lassen. Geht es dir um irgend welche Interna? Dann wirst du eben genauer werden müssen. Bei unix-shells eben über $? und bei sqlshells eben das entsprechende Äquivalent.
-
tallan schrieb:
es geht darum ein frontend zu schreiben das z.b für sh oder sqlplus eine kommandohistory änhlich wie bei der bash realisiert.
Sowas gibt es doch schon längst. Nennt sich man: rlwrap und ist verdammt praktisch, benutze ich täglich.
-
nman schrieb:
tallan schrieb:
es geht darum ein frontend zu schreiben das z.b für sh oder sqlplus eine kommandohistory änhlich wie bei der bash realisiert.
Sowas gibt es doch schon längst. Nennt sich man: rlwrap und ist verdammt praktisch, benutze ich täglich.
ist mir bekannt
aber ich tippe das die aufgabenstellung nicht als gelöst gilt wenn ich per exec rlwrap starte
ich vermute die lösung meines probelms liegt darin system() zu nutzen und den retun weg abzufragen allerdgins weiss ich nicht wie ich aus prozess 1 den return werden von system(command) im prozess 2 abfragen kann
-
Dein Weg ist einfach viel umständlicher als nötig; schau Dir eben die rlwrap-Sourcen an und pick Dir das raus, was Du haben möchtest.
Oder ist die Aufgabenstellung genau so, dass Du das mit der Kirche ums Kreuz lösen musst?
-
ich hab mir rlwrap jetzt angesehen allerdings reicht mein verständnis wohl nicht wircklich um den knackpunkt zu finden, eigentlich sieht es relativ ähnlich aus,
ich lese per readline befehle ein gebe sie an den kindprozess
dann soll der prozess der readline ausführt warten ( das ist noch mein problem )
bis das kind den befehl abgearbeitet hatdieser schritt wird in rlwrap wenn ich es richtig verstanden habe auch gemacht, und es ist auch vorgegeben das ein 2ter prozess die daten auswertet.
um den ablauf darzustellen
P1
Daten einlesen
Daten an P2 senden
warten bis P2 fertig ist
und dann wieder von vorneP2
Programm starten (einmalig)
Daten einlesen / verarbeiten
sofern output -> zurückgebenCode von P2
dup2(pipeVtoK[0],0); /* Stdout des Vaters = Stdin des Kindes */ close(pipeVtoK[1]); /* auf lesepipe wird nicht geschrieben */ dup2(pipeKtoV[1],1); // ausgabe auf Vater umleiten dup2(pipeKtoV[1],2); // fehlerausgabe auf Vater umleiten close(pipeVtoK[0]); // auf schreibpipe wird nicht gelesen system("sh");
Wenn ihr eine bessere / einfacherere möglichkeit kennt bin ich für jede Hilfe / Anregung dankbar.