Execl will nicht starten.
-
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); }
-
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 ?
-
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 ...
-
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?
-
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 ?
-
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"; } */ } } }
-
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 ?
-
OK, ich habs schon mit system ...
-
bluepeople12 schrieb:
OK, ich habs schon mit system ...
Ähh, was hast du überhaupt vor?
-
Ich hab hier eine Liste an Dateien (Textdateien). In ihnen soll was gesucht werden und dies soll angezeigt werden.
Dass die Dateien existieren, ist garantiert. Dass da was drin ist, auch.
Und mit dem C++-Befehl system will ich grep starten, sodass mein Prozess nicht beendet wird ... sondern mehrfach, da ich ja jede Datei mit grep starten möchte und nach bestimmten Suchwörtern suche.Das hab ich vor ...
Ist da was falsch dran?
-
bluepeople12 schrieb:
Und mit welchem Befehl starte ich einfach einen neuen Prozess ohne ihn zu beenden ?
fork
edit: "ohne ihn zu beenden" ist natürlich Quark, bei exec wird nichts beendet, sondern ersetzt. Der übliche Weg, ein anderes Programm als Unterprozess zu starten, besteht in einer Kombination aus fork und exec: Erst fork, um einen Kindprozess abzuspalten. Dann im Kindprozess exec.
(oder system)