Execl will nicht starten.



  • Ich hab hier folgende Zeilen:

    std::string com;
              com.append("grep");
              execl(com.c_str(), "-n", "-w", word.c_str(), list_files.at(i + 1).c_str(), (char*) 0);
    

    Doch irgendwie will er das Programm grep nicht starten. Warum nicht ? Was mach ich falsch ?

    Edit: Fehlermeldungen kommen auch keine ...



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x) 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.


  • Mod

    bluepeople12 schrieb:

    Edit: Fehlermeldungen kommen auch keine ...

    Meinst du damit nur, auf dem Bildschirm kommen keine Fehlermeldungen? Oder hast du tatsächlich mal errno geprüft? Falls du das noch nicht getan hast: Mach mal.



  • Also da kommt 2 raus. Hab nachgeschaut, bedeutet, dass er grep nicht findet.

    Aber das finde ich irgendwie komisch, weil wenn ich das in der bash starte, dann funktionierts problemlos ... und jetzt will er hier nicht starten.

    Was kann ich machen, damit das funktioniert ?



  • man: execl erwartet den kompletten Pfad zum Binary! Was du willst ist execlp . Das wertet genau wie bash die $PATH-Umgebungsvariable aus. Außerdem sollte der erste Parameter (argv[0]) der Aufrufstring sein und kein direkter Parameter.

    if(execlp(com.c_str(), com.c_str(), "-n", "-w", word.c_str(), list_files.at(i + 1).c_str(), (char*) 0) == -1) {
      perror("execlp");
      exit(1);
    }
    

  • Mod

    Ach, das hätte ich auch gleich sehen können. Zwei Fehler (den zweiten siehst du erst, wenn du den ersten behebst):
    1. execl startet keine Shell. Einfach nur grep reicht daher nicht, da keine Suchpfade durch die Shell ausgewertet werden. Das Programm ist in der Regel /bin/grep. Oder du startest eine Shell (z.B. /bin/bash) und übergibst dieser wiederum das grep als auszuführendes Kommando (in der Regel Die Kommandozeilenoption -c, um einer Shell Befehle zu übergeben).
    2. execl startet keine Shell 😃 . Das heißt auch, dass keine Standardargumente übergeben werden. grep und die Shells erwarten als ihren ersten Kommandozeilenparameter aber sich selbst.

    Hier ein ganz einfaches Beispiel, dass dir helfen sollte (das Beispiel nimmt an, dass dein Programm test.cc heißt):

    #include <unistd.h>
    #include <cstddef>
    
    int main()
    {
      execl( "/bin/grep",  "/bin/grep", "test", "test.cc", NULL);
    }
    

    edit: Zu langsam...



  • Ich habs jetzt mit der Funktion execlp versucht, aber bei mir kommt dann immer raus:

    : No such file or directory

    Seid ihr euch da sicher mit der Funktion ?


  • Mod

    Passt doch. Das ist das was grep dir meldet. Anscheinend passen deine Argumente nicht.



  • Was ich komisch finde ist folgendes...

    wenn ich

    execlp("grep", "grep", "-n", "-w", "a", "/home/User1/CPP/uebungsblatt-8/StringTest.cpp", reinterpret_cast<char*> (0) );
    

    schreibe, funktioniert alles wunderbar, er schreibt mir das, was ich will.

    Wenn ich aber schreibe

    execlp("grep", "grep", "-n", "-w", word.c_str(), list_files.at(i + 1).c_str(), reinterpret_cast<char*> (0));
    

    Und ich hab mir sowohl word.c_str() ausgeben lassen als auch list_files.at(i + 1).c_str()

    word ist das gesuchte word und list_files ist die liste der dateien (alle als std::string in einem std::vector) und die dateien gibt es ... so wie auch die im obigen beispiel ...


  • Mod

    bluepeople12 schrieb:

    Und ich hab mir sowohl word.c_str() ausgeben lassen als auch list_files.at(i + 1).c_str()

    word ist das gesuchte word und list_files ist die liste der dateien (alle als std::string in einem std::vector) und die dateien gibt es ... so wie auch die im obigen beispiel ...

    Ich wette dagegen.



  • Wieso?


  • Mod

    bluepeople12 schrieb:

    Wieso?

    Weil Computer erfahrungsgemäß keine so krassen Fehler machen. Menschen schon.

    Um deinem Problem auf die Spur zu kommen, mach mal:
    execl( "/bin/ls", "/bin/ls", NULL);



  • SeppJ schrieb:

    bluepeople12 schrieb:

    Wieso?

    Weil Computer erfahrungsgemäß keine so krassen Fehler machen. Menschen schon.

    Um deinem Problem auf die Spur zu kommen, mach mal:
    execl( "/bin/ls", "/bin/ls", NULL);

    OK, der Befehl funktioniert. Mir wird eine Liste von Dateien ausgegeben ... die in demselben Ordner sind wie ich mich gerade befinde ...

    Und nun ?



  • Nun überprüf nochmal, ob die Argumente richtig sind. Hängen da vielleicht noch Leerzeichen oä dran?



  • Ok, hab nochmal alles durchgecheckt und als ich dann die Längen der strings verglichen hatte, kam raus, dass da doch wohl ein Zeichen zuviel war ...

    Aber jetzt habe ich ein ganz anderes Problem. Und zwar wird das Programm gleich nach dem ersten Durchlauf beendet ...
    Wie kann ich das verhindern ?


  • Mod

    bluepeople12 schrieb:

    Aber jetzt habe ich ein ganz anderes Problem. Und zwar wird das Programm gleich nach dem ersten Durchlauf beendet ...
    Wie kann ich das verhindern ?

    Mehr Druchläufe machen!

    Ernsthaft: Was soll so eine Frage? Wir kennen von deinem Programm drei Zeilen. Und die drei Zeilen haben allesamt nichts mit der Ablaufsteuerung zu tun. Wie sollen wir da jetzt diagnostizieren, was falsch ist?



  • Nunja ... wenn ich die Zeilen mit dem Befehl execlp auskommentiere ... zeigt mir mein Programm jeden Durchlauf an.

    Wenn ich jedoch da lasse ... dann ist der erste Durchlauf fertig und das wars dann. Und ich denk mir dann als Folge, dass es an dem Befehl liegt.

    Hier mal die Schleifen, um die es geht (dabei ist execlp auskommentiert):

    Es wird hier geschaut, ob zwei strings gleich sind, und wenn ja, dann soll der Dateiname ausgegeben werden mit ein paar Zeilen aus dem Inhalt (und das geschieht über das Programm grep).

    for (size_t i = 0; i < list_files.size() - 1; i++)
        {
          for (size_t j = 0; j < list_fileids.size(); j++)
          {
            // std::cout << "i: " << i << "\tj: " << j << "\n";
            if (list_files.at(i).compare(list_fileids.at(j)) == 0)
            {
              // std::cout << list_files.at(i) << "\n";
              // std::cout << i << "\n";
              list_files.at(i + 1) = list_files.at(i + 1).replace(
                list_files.at(i + 1).size() - 1, 1, "");
              std::cout << list_files.at(i + 1).c_str() << "\n";
    /*
              if (execlp("grep", "grep", "-n", "-w",
                word.c_str(), list_files.at(i + 1).c_str(),
                NULL) == -1);
              {
                std::cout << "Error\n";
              }
    */
            }
          }
        }
    

  • Mod

    😮 Und was wundert dich da dran jetzt? Weißt du überhaupt, was die exec-Funktionen machen? Mal eine Manpage gelesen oder ein Beispiel angeguckt? Das exec alleine ersetzt den aktuellen Prozess mit einem neuen!



  • SeppJ schrieb:

    bluepeople12 schrieb:

    Aber jetzt habe ich ein ganz anderes Problem. Und zwar wird das Programm gleich nach dem ersten Durchlauf beendet ...
    Wie kann ich das verhindern ?

    Mehr Druchläufe machen!

    Der war gut. 😃 👍



  • SeppJ schrieb:

    😮 Und was wundert dich da dran jetzt? Weißt du überhaupt, was die exec-Funktionen machen? Mal eine Manpage gelesen oder ein Beispiel angeguckt? Das exec alleine ersetzt den aktuellen Prozess mit einem neuen!

    Und mit welchem Befehl starte ich einfach einen neuen Prozess ohne ihn zu beenden ?


Anmelden zum Antworten