variablen vertauschen

Dieses Thema im Forum "C/C++" wurde erstellt von Ale-x, 28.06.2007.

  1. Ale-x

    Ale-x bash lehrling

    Dabei seit:
    13.04.2007
    Beiträge:
    109
    Zustimmungen:
    0
    Ort:
    Osnabrück
    also ich hab folgenden wunsch
    es gibt 2 variablen
    a=10
    b=20

    nun starte ich das programm
    ./foo a b

    danach sieht es so aus
    a=20
    b=10

    ein kollege hat mir schon was fertig gemacht was aber noch nicht so wie es soll funktioniert
    er gibt die werte zwar richtig aus aber es tauscht die variablen nicht untereinander aus


    und ich hab gar keine ahnung von c und dachte mir könnte jemand hier helfen????
    Code:
    #include <stdio.h>
    
    int main(int *argc, char *argv[])
    {
           if(argc!=3)
           {
                   printf("Nicht genug Argumente\n");
                   exit(-1);
           }
    
           char change[1024];
           char save1[1024];
           char save2[1024];
    
           strcpy(save1,getenv(argv[1]));
           strcpy(save2,getenv(argv[2]));
    
           // Anzeigen
           printf("%s=%s %s=%s\n",argv[1],getenv(argv[1]),argv[2],getenv(argv[2]));
    
           // 1. Variable ändern
           setenv(argv[1],save2,1);
    
           // 2. Variable ändern
           setenv(argv[2],save1,1);
    
           printf("%s=%s %s=%s\n",argv[1],getenv(argv[1]),argv[2],getenv(argv[2]));
    }
    
    
     
  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 nibel, 28.06.2007
    Zuletzt bearbeitet: 28.06.2007
    nibel

    nibel Doppel-As

    Dabei seit:
    29.12.2006
    Beiträge:
    114
    Zustimmungen:
    0
    Dazu benötigst du pointer du kannst sie sonst nicht global ändern
    .
    .
    .
    EDIT (autom. Beitragszusammenführung) :
    .

    void tausche(int *eins, int *zwei) {
    int hilf;
    hilf = *eins;
    *eins = *zwei;
    *zwei = hilf;
    }
     
  4. #3 David_1980, 29.06.2007
    David_1980

    David_1980 Jungspund

    Dabei seit:
    28.06.2007
    Beiträge:
    11
    Zustimmungen:
    0
    Ort:
    Hannover
    Das sieht so aus, als möchtest Du den Wert zweier globaler Variablen ändern.

    Die gute Nachricht:
    Auf den ersten Blick sieht das Programm ganz korrekt aus (bis auf ein paar "Schönheitsfehler"). Und ich bin mir auch ziemlich sicher, das es die Umgebungsvariablen vertauscht.

    Die schlechte Nachricht:
    Ein Prozess kann, soweit ich informiert bin, nicht die Umgebung seines Elternprozesses ändern. Genaugenommen kann er überhaupt nicht in den Adressraum eines anderen Prozesses greifen, zumindest nicht im User-Mode, ich denke im Kernel-Mode könnte man.
    Du kannst bestenfalls wie in Deinem Programm beschrieben die Umgebungsvariablen anpassen und im gleichen Prozess mit dieser Umgebung weiterarbeiten, oder einen neuen Kindprozess starten und mit dieser geänderten Umgebung initialisieren.
    Aber falls Du vorhattest dieses Programm z.B. von der Shell ausaufzurufen, oder in einem bash-script zu verwenden, wird nicht der gewünschte Effekt erreicht werden. Die Umgebungsvariablen des Aufrufers ändern sich nicht.

    Falls jemand anders weiss wie man sowas erreichen kann - mich würde es auch interessieren.

    Um Daten zwischen verschiedenen Prozessen auszutauschen kann man Pipes, Sockets oder Dateien verwenden. Aber ich denke diese Wege sind wohl Overkill für diese Aufgabe, oder?

    David
     
  5. #4 Ale-x, 29.06.2007
    Zuletzt bearbeitet: 29.06.2007
    Ale-x

    Ale-x bash lehrling

    Dabei seit:
    13.04.2007
    Beiträge:
    109
    Zustimmungen:
    0
    Ort:
    Osnabrück
    @david
    also es sollen variablen vertauscht werden die ich selber in einem script vorher festlege


    aus diesem script heraus will ich das programm aufrufen zum vertauschen z.b

    a=10
    b=14
    <befehl1>
    <befehl2>
    ./foo a b>
    echo a=$a -> ausgabe a=14

    ./foo soll also die variablen vertauschen
    hab jetzt folgendes
    Code:
    #include <stdio.h>
    
    int main(int *argc, char *argv[])
    {
           if(argc!=3)
           {
                   printf("Nicht genug Argumente\n");
                   exit(-1);
           }
    
           char save1[1024];
           char save2[1024];
    
           strncpy(save1, getenv(argv[1]), strlen(getenv(argv[1])) );
           strncpy(save2, getenv(argv[2]), strlen(getenv(argv[2])) );
    
           // Anzeigen
           printf("%s=%s %s=%s\n",argv[1],getenv(argv[1]),argv[2],getenv(argv[2]));
    
           // 1. Variable ändern
           setenv(argv[1],save2,1);
    
           // 2. Variable ändern
           setenv(argv[2],save1,1);
    
           printf("%s=%s %s=%s\n",argv[1],getenv(argv[1]),argv[2],getenv(argv[2]));
           system("/bin/bash");
           return(0);
    }
    
    
    EDIT: also es funktioniert man muss nur vorher die variablen exportieren dann funktioniert es
    die .bashrc wird wohl nochmal aufgerufen vielleicht hat noch jemand eine idee wie man das anders machen kann
     
  6. #5 David_1980, 29.06.2007
    David_1980

    David_1980 Jungspund

    Dabei seit:
    28.06.2007
    Beiträge:
    11
    Zustimmungen:
    0
    Ort:
    Hannover
    Ein Moment mal .... imho bekommen prozesse immer kopien der umgebungsvariablen, daher können sie nicht die Umgebung des Elternprozesses ändern. kann es sein, das du folgendermaßen vorgehst:
    1. wahrscheinlich führst du dieses skript aus:
    und wenn es durchgelaufen ist gibst du diesen Befehl ein:
    Wenn das so ist, dann verstehe ich warum das bei Dir "funktioniert". Das tut nämlich nur so. Aber wenn Du damit zufrieden bist, dann ist ja alles in Ordnung. Aber ich glaube Du solltest mal ein shell-script schreiben, das so alles erledigt:
    Code:
    a=10
    b=14
    export a
    export b
    ./foo a b
    echo a=$a
    echo b=$b
    Ich denke wenn Du dieses Skript ausführst, wird das Ergebnis nicht Deinen Wünschen entsprechen.
    Ich hab leider grad keine Zeit, da ich noch einen Termin habe. Aber melde Dich nochmal, wenn Du das ausprobiert hast und erzähl mal ob ich recht hatte. Saug mir mangels Zeit nämlich grad aus den Fingern. Dann erklär ich Dir auch warum das so ist.
     
  7. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  8. Ale-x

    Ale-x bash lehrling

    Dabei seit:
    13.04.2007
    Beiträge:
    109
    Zustimmungen:
    0
    Ort:
    Osnabrück
    also so in der shell funktionierts
    [root@jacque tools]# a=10
    [root@jacque tools]# b=20
    [root@jacque tools]# ./a a b
    a=10 b=20
    a=20 b=10
    [root@jacque tools]# echo $a
    20


    im script nicht
     
  9. #7 David_1980, 30.06.2007
    David_1980

    David_1980 Jungspund

    Dabei seit:
    28.06.2007
    Beiträge:
    11
    Zustimmungen:
    0
    Ort:
    Hannover
    Du sagst im Skript nicht. Hmmm, ich nehme mal an, das ist nicht gerade das, was ich eine detailierte Fehlerbeschreibung nennen würde. Aber ich kann mir auch so denken was passiert.... Wenn du das als Skript verwendest, werden wahrscheinlich nicht einmal die Ausgaben am Ende des Programmes stattfinden richtig?

    Das Problem liegt darin, wie Dir mit dem obigen Programm vorgespielt wird, das Umgebungsvariablen verändert wurden. Also ich erzähl mal Schritt für Schritt was da passiert. Wir nehmen den ersten Fall, du tippst alle Befehle in die bash ein. Das läuft so ab:
    1. Du setzt die Umgebungsvariablen a und b
    2. Du startest das Tausch-Programm und übergibst ihm die Namen der zu vertauschenden Variablen. Das Programm wird in einem neuen Prozess, als Kindprozess Deiner Bash gestartet.
    3. Im Tauschprogramm werden nun die Inhalte der beiden Umgebungsvariablen vertauscht. Dies geschieht aber in der Umgebung des Tauschprogramms, nicht in der Umgebung des Elternprozess.
    4. Jetzt kommt der fiese Trick/Fehler in dem Programm. Mit dem Befehl
      Code:
      system("/bin/bash");
      startest Du eine weitere Bash. Diese ist nun ein Kindprozess des Tauschprogramms und kopiert die Umgebung des Tauschprogramms. In dieser Umgebung befinden sich nun ebenfalls die vertauschten Variablen.
    5. In dieser neuen Bash gibst Du nun die echo-Befehle ein, die Dir den Inhalt der Umgebungsvariablen a und b ausgeben. Dieser Inhalt ist tatsächlich vertauscht. Aber bedenke: Wir befinden uns bereits im Kind-Kind-Prozess der ursprünglichen Shell. Und zur Zeit laufen immer noch alle 3 Prozesse! Und die Variablen a und b die Du hier abfragst sind schon lange nicht mehr die ursprünglichen die Du vertauschen wolltest.
    Dir ist das mit der neuen Bash wahrscheinlich aus dem Grund nicht aufgefallen, weil sie im selben Fenster läuft wie die ursprüngliche. Aber Du kannst das schnell überprüfen, indem Du die oben genannten Schritte noch einmal durchführst und dann beginnst die Prozesse Schritt für Schritt zu beenden. Also nachdem Du das "positive" Ergebnis gesehen hast, gibst Du einmal "exit" ein. Die Kind-Kind-Shell wird beendet. Aber was ist das?! Das Fenster ist noch auf!

    Richtig, denn nach dem der "system("/bin/bash")"-Befehl nun endlich zurückgekehrt ist, kann das Tauschprogramm fortfahren. Naja, witzig wäre wenn ich noch ein paar printf's wären, die ausgaben würdest du nämlich jetzt erst bekommen. Aber das Programm beendet sich jetzt mit "return 0". Damit ist jetzt auch der letzte Kindprozess beendet. Die Beendigung dieses Prozesses hast Du aber auf dem Bildschirm nicht mitbekommen.

    Jedenfalls sind wir nun endlich in der "richtigen" also der ursrünglichen Bash angekommen. Frage doch jetzt nochmal per echo den Inhalt der Variablen ab! Jetzt sollte zu sehen sein, daß sie sich in Wahrheit nicht verändert haben und jede ihren ursprünglichen Wert besitzt.

    Puh! Muss ich jetzt noch erklären warum das Skript Dir das alles nicht vorgaukelt?

    Ok, ganz kurz, ich nehme an, jetzt sollte es ohnehin schon klar sein.

    Also Du startest eine Bash (1. Prozess). Du startest das Skript(2.). Das skript startet das Programm(3. Proc). Im 3. Proc werden die Variablen vertauscht. Bisher gibt es nicht mal eine Ausgabe auf der Console. Das Programm startet eine neue Bash. Die neue Bash wartet auf deine Eingabe! An dieser Stelle dachtest Du wahrscheinlich, das Skript sei zu Ende und es wäre überhaupt nichts passiert, denn auf der Console gibt es bislang noch keine Ausgaben.

    Irrtum! Beweis: Gib "exit" ein. Die Bash wird beendet. Das Programm wird beendet. (Damit ist die letzte Umgebung verschwunden in der die Variablen vertauscht waren). Wir befinden uns jetzt wieder im Skript-Prozess. Dieser gibt nun die Variablen aus, die sich nicht verändert haben. Dann beendet sich der skript prozess und wir sind in der ursprünglichen Bash. Falls die Variablen erst im Skript erzeugt und mit "export" zu Umgebungsvariablen wurden, dann sind sie jetzt nicht einmal mehr vorhanden, was leicht mit echo nachzuprüfen ist.

    Ok, damit sollte alles klar sein.

    Wozu brauchst Du das überhaupt? Ich meine das geht mit Bash-Boardmitteln doch viel einfacher! Sowas ist schneller geschrieben, genau genommen innerhalb von 45 Sekunden, wenn man echt langsam ist, und ist auch schneller in der Performance, da keine neuen Prozesse gestartet werden müssen. Wenn es echt nur um das Vertauschen zweier Variablen innerhalb des Skripts geht, dann macht man das so:
    Code:
    # Initialisierung
    a=14
    b=10
    # Vertauschung
    tmp=$b
    b=$a
    a=$tmp
    
    Wenn es Dir darum geht, diesen kurzen Programmcode nicht überall im skript zu wiederholen, da er häufig vorkommt, dann schreib Dir doch eine Funktion/Makro. Syntax dazu findest Du hier: http://www.ss64.com/bash/function.html

    Ich hoffe das hilft Dir weiter.

    Ein Prozess kann und sollte auch nicht in dem Adressraum (Speicherbereich) eines anderen herumfuhrwerken.

    PS: Liest man solange Postings überhaupt?
    :schlaf:
     
Thema:

variablen vertauschen

Die Seite wird geladen...

variablen vertauschen - Ähnliche Themen

  1. Linux 4.5 will UEFI-Variablen besser schützen

    Linux 4.5 will UEFI-Variablen besser schützen: Das Löschen bestimmter UEFI-Variablen kann manche Rechner nicht mehr startbar machen. Das kommende Linux 4.5 ergreift Maßnahmen dagegen, die im...
  2. Textdatei zeilenweise in durchnummerierte Variablen schreiben

    Textdatei zeilenweise in durchnummerierte Variablen schreiben: Hi Leute, ich versuche folgendes Problem zu lösen. Ich möchte eine Textdatei einlesen und den Inhalt jeder Zeile in immer eine neue Variable...
  3. mysql Select Abfrageergebnis in unterschiedlichen Variablen sichern

    mysql Select Abfrageergebnis in unterschiedlichen Variablen sichern: Hallo zusammen, es geht um folgenden Teil meiner .sh-Datei: NumberCheck=`mysql $SQL_ARGS "SELECT lkw, Firma FROM adb_group WHERE...
  4. Teil einer Variablen auslesen und in neue Variable schreiben

    Teil einer Variablen auslesen und in neue Variable schreiben: Hallo, ist für Euch bestimmt ganz einfach, aber trotz googlen komme ich nicht auf eine Lösung. In Variable x habe ich stehen: xy,ab Nun möchte...
  5. Inhalt einer Variablen aus Batch an Shellscript übergeben

    Inhalt einer Variablen aus Batch an Shellscript übergeben: Hallo, ich komme einfach nicht drauf. Wie kann ich den Wert aus einer Variablen eines Batches an mein Shellscript übergeben? So? #...