Woran erkenne ich das ein befehl funktioniert hat

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von Nano, 08.03.2009.

  1. Nano

    Nano Foren As

    Dabei seit:
    02.12.2006
    Beiträge:
    93
    Zustimmungen:
    0
    Hallo zusammen, ich schreibe in c ein programm das eine shell als kind hat dieser befehle über pipes sendet, die shell sie ausführt und per pipe daten zurückgibt ich hab nun folgendes problem bei dem ganzen, mein vaterprozess der die daten an die shell gibt und von ihr empfängt wird per select so lange schlafen geschickt bis auf der von der shell ausgenden pipe ( stdout ) daten kommen, das funktioniert bei allen befehlen mit rückgabe wie z.b ls , cat etc ohne problem, allerdings weiss ich woran ich sehe ob z.b. ein befehl wie mkdir "fertig" ist da er ja im erfolgsfall keine rückgabe liefert und so meine pipe auch keine daten bekommt folglich der prozess weiter schläft.

    Es handelt sich zwar um ein C programm denke aber das diese frage eher hier rein passt.

    Nochmal um es etwas vereinfacht darzustellen

    Prozess 1 schickt über pipes einen befehl an Prozess 2 ( hier läuft eine Shell )
    Prozess 1 geht schlafen bis Daten von P2 kommen ( per select gelöst )
    Prozess 2 arbeitet befehl ab, daten von stdout werden über die pipe an P1 gesendet

    Problem : P2 erhält befehl der keine rückgabe über stdout liefert.
    Wie z.b chmod oder mkdir etc...

    Wie kann ich abfragen ob das geschehen ist ?
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Tomekk228, 08.03.2009
    Tomekk228

    Tomekk228 Lebende Foren Legende

    Dabei seit:
    14.08.2007
    Beiträge:
    2.417
    Zustimmungen:
    0
    Ort:
    /home/tomekk/
    Gut 99% der Befehle haben den Verbose mode.

    Edit> Was hast du eigentlich vor? Eine Shell in einer Shell zu programmieren? Oo
     
  4. larry

    larry Tripel-As

    Dabei seit:
    27.11.2007
    Beiträge:
    159
    Zustimmungen:
    0
    Wenn du in der Shell einen Programm startest, kannst du mit echo $? den Rückgabewert abfragen.
    Wenn du in der Shell ein Programm ausführst, wird zuerst ein Kind erzeugt. Das könnte dir evtl. auch weiter helfen.
     
  5. #4 Nano, 08.03.2009
    Zuletzt bearbeitet: 08.03.2009
    Nano

    Nano Foren As

    Dabei seit:
    02.12.2006
    Beiträge:
    93
    Zustimmungen:
    0
    danke aber das hilft an der stelle nicht da ich den befehl nicht ändern will der eingegeben wird.

    ich schreibe ein frontend für kommandozeilenorientierte programme, die shell war hier nur ein beispiel, sinn des ganzen ist es für programm die keine history funktion ( wie in bash ) eben dies zu bieten.
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    $? ist mir bekannt wobei diesen zu erfragen bei der shell ein problem darstellt, weil der prozess1 ja solange schläft bis er daten erhält und das programm auch nicht ausschließlich für die shell gedacht ist sondern auch für andere kommandozeilen orientierte programme.
     
  6. #5 Tomekk228, 08.03.2009
    Tomekk228

    Tomekk228 Lebende Foren Legende

    Dabei seit:
    14.08.2007
    Beiträge:
    2.417
    Zustimmungen:
    0
    Ort:
    /home/tomekk/
    Also nochmal, was willst du genau machen? :D

    Eine Historyfunktion für was? Für mkdir z.b oder wie?

    Beschreib mal genau was du vor hast.
     
  7. Nano

    Nano Foren As

    Dabei seit:
    02.12.2006
    Beiträge:
    93
    Zustimmungen:
    0
    ich möchte ein frontend für kommandozeilenorientierte programme schrieben, dazu kommen logfiles über ein und ausgabe etc.

    So hätte man z.b für programme wie sqlplus oder die normale shell eine kommandohistory wie in der bash...

    das hab ich soweit auch alles fertig implementiert, mein problem liegt in befehlen die keinen output erzeugen, da ich im parent prozess auf die rückgabe der daten warte.

    Ich suche also eine möglichkeit festzustellen ob in einem laufenden "programm" wie z.b einer shell oder sqlplus die ich in einem gesonderten prozess starte, der befehl ausgeführt worde
    Code:
    //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);
            }
    } 
    
    z.z habe ich es so gelöst das ich im 2ten prozess daten eingaben lese sie an den prozess weiterleite den aktuellen mit select verzögere bis ich die antwort des 2ten prozesses ( siehe code beispiel ) erhalte. Das funkioniert allerdings nur bei befehlen die auch einen output erzeugen, meine frage :

    Wie mache ich das :
    a)bei Befehlen die keinen Output erzeugen
    b) nicht shell spezifisch es könnte auch z.b sqlolus im prozess laufen
    c) ohne das der prozess in dem die shell oder was auch immer läuft beendet wird
     
  8. #7 marcellus, 09.03.2009
    marcellus

    marcellus Kaiser

    Dabei seit:
    09.05.2007
    Beiträge:
    1.392
    Zustimmungen:
    0
    Vielleicht wirst du dich schon gefrag haben wieso es in c immer "INT main(.." ist und nicht "void main(.." ist, das liegt daran das dir Programme auch rückgabewerte zurückgeben.

    Das könntest du ausprobieren mit "ls dum || echo fail && echo ok"

    Ich bin mir zwar nicht sicher was genau execl ausgibt, aber mit system() hast du vielleicht etwas mehr spaß.

    Hier die return values zu system()
     
  9. Nano

    Nano Foren As

    Dabei seit:
    02.12.2006
    Beiträge:
    93
    Zustimmungen:
    0
    die übergabe der parameter beim programmstart ist ja in diesem fall völlig egal da die shell bzw das programm was auch immer im prozess x gestartet wird erst zur laufzeit entsteht.

    Aber danke für den hinweis auf system mir war nicht klar das es den befehlsstatus zurückgibt, werd gleich mal versuche das dem entsprechend zu ändern.
     
  10. #9 tuxlover, 09.03.2009
    tuxlover

    tuxlover Der den Tux knuddelt

    Dabei seit:
    26.10.2005
    Beiträge:
    2.106
    Zustimmungen:
    0
    Ort:
    berlin
    echo $?

    >>0 --> befehl wurde erfolgreich ausgeführt

    >>1 --> befehl hatte einen fehler
     
  11. #10 Gott_in_schwarz, 09.03.2009
    Gott_in_schwarz

    Gott_in_schwarz ar0

    Dabei seit:
    22.04.2007
    Beiträge:
    546
    Zustimmungen:
    0
    Ort:
    Niedersachsen
    <klugshice>
    Code:
    ls dum || echo fail && echo ok
    ist falsch. Das muss
    Code:
    ls dum && echo success || echo fail
    heißen.
    </klugshice>
     
  12. #11 floyd62, 09.03.2009
    floyd62

    floyd62 Routinier

    Dabei seit:
    01.05.2007
    Beiträge:
    309
    Zustimmungen:
    0
    Wenn du bei execl() an die Shell die Option "-i" mit übergibst, wird diese in den interaktiven Modues gesetzt. Dann liefert sie (vermutlich auf stderr) einen Prompt (je nach Zusammenhang PS1, PS2 oder PS3), den dein Programm einfach erkennen kann.

    Genau so kannst du z.B. bei sqlplus auf die verschiedenen Prompts ("SQL>", danach Zeilennummern "2", "3", ... bis das Statement komplett eingegeben ist) warten (die kommen allerdings auf stdout).

    Für jedes Programm, das du so steuern willst, musst du also rausbekommen, was für Prompts es schickt, und auf welchem Weg.

    Grüsse

    NB: Evtl. wäre es eine Überlegung wert, die Kommunikation zwischen deinem Master- und Slave-Prozess über Pseudo-TTYs (siehe pty(7)) abzuwickeln statt über Pipes; dann bekämen interaktive Programme - wie die Shell - eine "normale" Umgebung statt einer Simulation mit Pipes, die sich ja doch deutlich anders verhalten als Terminals ;-)
     
  13. #12 Nano, 09.03.2009
    Zuletzt bearbeitet: 09.03.2009
    Nano

    Nano Foren As

    Dabei seit:
    02.12.2006
    Beiträge:
    93
    Zustimmungen:
    0
    die shell war ein beispiel es kann auch z.b sqlplus sein womit diese lösung leider nicht allg. funktioniert...
    wäre es nur die shell könnte ich auch einfach (befehl ; echo " ") übergeben und mit select warten
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    danke für den tip ich werde mit pty gleich anschauen,
    was die lösung mit dem promptzeichen betrifft wäre diese leider nicht allg. lösbar
     
  14. #13 floyd62, 10.03.2009
    floyd62

    floyd62 Routinier

    Dabei seit:
    01.05.2007
    Beiträge:
    309
    Zustimmungen:
    0
    Hi Nano,

    du hast natürlich recht, eine "allgemeine" Lösung gibt es nicht. Eventuell ist das aber auch gar nicht wirklich nötig, dein Programm muss ja nicht intelligenter sein, als der, der vor der Tastatur sitzt, und der das Master-Programm kontrolliert.

    Was macht der User, wenn er einige Zeit lang nichts sieht? Er drückt irgendwelche Knöpfe ...

    Also: dein Programm kann entweder versuchen ebenso schlau zu sein, und nach einem (konfigurierbaren) Timeout irgendwelche sinnfreien/konfigurierbaren Eingaben (RETURN, SPACE, Control-L, ...) an das Slave-Programm zu schicken ... oder du überwachst mit select() einfach gleichzeitig sowohl die Tastatur, über die dein Master-Programm die Benutzereingaben erhält, und die Pipes, über die es stdout und stderr (und ggf. weitere Kanäle) vom Slave zurückbekommt, und überlässt es vollkommen dem Anwender, zu reagieren oder eben nicht ...

    Grüsse
     
  15. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  16. Nano

    Nano Foren As

    Dabei seit:
    02.12.2006
    Beiträge:
    93
    Zustimmungen:
    0
    danke floyd , das problem bei der sache ist nur das es so durchaus vorkommen kann das ein befehl länger dauert simples beispiel (sleep 10 ; wasauchimmer) , wenn der user jetzt nach sagne wir einem timeout von 5 sekunden wieder befehle eingeben kann bekommt er mitten in seine eingabe die antwort des anderen prozesses
     
  17. #15 Gott_in_schwarz, 10.03.2009
    Gott_in_schwarz

    Gott_in_schwarz ar0

    Dabei seit:
    22.04.2007
    Beiträge:
    546
    Zustimmungen:
    0
    Ort:
    Niedersachsen
    Consider:
    Code:
    #!/usr/bin/env perl
    use strict;
    use warnings;
    use Term::ReadLine;
    
    my $term = Term::ReadLine->new('foo');
    
    while (my $line = $term->readline('$ ')) {
        print "got: $line\n";
    }
    Wie könnte man diesem Script Eingaben übergeben? (Versuch macht kluch.)
    Ich würde schätzen dazu braucht man libexpect oder so.
     
Thema:

Woran erkenne ich das ein befehl funktioniert hat

Die Seite wird geladen...

Woran erkenne ich das ein befehl funktioniert hat - Ähnliche Themen

  1. Befehl funktioniert in bash aber nicht in sh - Woran liegt das?

    Befehl funktioniert in bash aber nicht in sh - Woran liegt das?: Ich möchte die ersten 10 Zeichen einer Variable ausgeben, was mit bash funtktioniert, mit sh aber nicht. Woran liegt das? Wie kann es in sh...
  2. Woran liegt es, das...

    Woran liegt es, das...: nur der volle PATH das gewünschte Ergebnis bringt? [user3@maerz ~]$ sudo /sbin/umount.cifs ~/Ressourcen [user3@maerz ~]$ mount /dev/sda2 on /...
  3. lange Bootzeit: woran liegt das?

    lange Bootzeit: woran liegt das?: Hi, ich habe mal die Zeit gesptoppt (Grub bereits gestartet): Es dauert 25sec bis der Bootloader geladen ist. Nach 65sec Starten die Skripte....
  4. Fehler in Grafik oder woran liegts?

    Fehler in Grafik oder woran liegts?: Hi zusammen. Ich habe meine Programmleiste mit neuen Icons bestücken wollen und bei der Symbolvergrößerung der neuen Icons ist mir ein Fehler in...
  5. woran seh ich was im kernel ist ?

    woran seh ich was im kernel ist ?: hab da mal wieder ein kleines problem. kann ich sehen was alles in den kernel miteincompiliert ist? welche module laufen und verfügbar sind,...