Seite 1 von 2

Problem beim Prozessauslesen

Verfasst: 27. Juli 2006 23:09
von slash-ex
Ich muss einen Prozess auslesen, bzw. vielmehr die Ausgabe eines kleinen Programmes namens: "cat /proc/partitions".
Also wenn ich diese Fuktion mittels QStringList tmp = getPrcOutP("cat /proc/partitions"); aufrufe passiert anscheinend nichts?!

Das Programm durchläuft anscheinend diese Schleife nicht:

Code: Alles auswählen

	while(!txt_stream->atEnd() )
	{
		std::cout<<"read output: ";
		QString tmp_str = txt_stream->readLine();
		output.append(tmp_str);
		std::cout<<tmp_str.toStdString()<<std::endl;
	}
Was habe ich falsch gemacht? Eigentlich erwarte ich dass mir eine Ausgabe über meine Partitionen ausgegeben wird die so aussieht:

Code: Alles auswählen

major minor  #blocks  name

   3     0   78150744 hda
   3     1   35840983 hda1
   3     2          1 hda2
   3     5   20394486 hda5
   3     6   17832118 hda6
   3     7    3550333 hda7
   3     8     530113 hda8
Die Funktion:

Code: Alles auswählen

QStringList getPrcOutP(QString cmd)
{
	QProcess *process = new QProcess();
	std::cout<<"try to open: "<<cmd.toStdString()<<std::endl;
	process->start(cmd, QIODevice::ReadOnly);
	if (!process->waitForStarted() )
		std::cout<<"process couldn't get opened"<<std::endl;


	QTextStream *txt_stream = new QTextStream(process);

	QStringList output;
	while(!txt_stream->atEnd() )
	{
		std::cout<<"read output: ";
		QString tmp_str = txt_stream->readLine();
		output.append(tmp_str);
		std::cout<<tmp_str.toStdString()<<std::endl;
	}

	return output;

	process->close();
}
Könnte mir jemand verraten, wass ich beim Aulesen von Konsolenausgaben zu beachten habe?

Verfasst: 28. Juli 2006 06:31
von Christian81
Das return ist falsch da process nicht geschlossen wird, process wird nicht gelöscht und Du wartest nicht auf das Signal
QProcess::finished

Verfasst: 28. Juli 2006 14:00
von slash-ex
An und für sich sollte es jetzt schon klappen! Aber irgendwie scheint der TextStream schon am Ende zus ein bevor er überhaupt anfängt! Ich weiß nicht wie man sonst noch die Konsolenausgabe abfängt!

Code: Alles auswählen

	while(!txt_stream->atEnd() )
	{
		std::cout<<"read output: ";
		QString tmp_str = txt_stream->readLine();
		output.append(tmp_str);
		std::cout<<tmp_str.toStdString()<<std::endl;
	}
Jetzt wird erst ein return geliefert, wenn der Prozess ein finished liefert.

Code: Alles auswählen

QStringList getPrcOutP(QString cmd)
{
	QProcess *process = new QProcess();
	std::cout<<"try to open: "<<cmd.toStdString()<<std::endl;
	process->start(cmd, QIODevice::ReadOnly);

	if (!process->waitForStarted() )
		std::cout<<"process couldn't get opened"<<std::endl;

	QTextStream *txt_stream = new QTextStream(process);

	QStringList output;
	while(!txt_stream->atEnd() )
	{
		std::cout<<"read output: ";
		QString tmp_str = txt_stream->readLine();
		output.append(tmp_str);
		std::cout<<tmp_str.toStdString()<<std::endl;
	}

	if(process->waitForFinished() )
	{
		process->close();
		std::cout<<"process finished: "<<std::endl;
		return output;
	}
}

Verfasst: 30. Juli 2006 12:08
von slash-ex
hat denn keiner ne idee? es liegt nicht am return.. bis dahin hätte ich ein cout<< bekommen. un im moment ist das einzige ein "process finished"

also wird nichts was der porocess ausgibt gelesen. es liegt auf jedenfall nicht am befehl ("cat", etc), an den absoluten pfaden... an den argumenten und auch nicht an den membern:
waitForStarted()
==>waitForStarted(1) hilft auch nicht.

mal ne frage? habe ich nun einen fehler gemacht oder ist das ein bug im framework?

mir ist einer aufgefallen als ich eine von QWidget abgeleitete Klasse in ein QListwidget einfügen wollte... alles assistant konform...

Verfasst: 30. Juli 2006 19:30
von slash-ex

Code: Alles auswählen

QStringList getPrcOutP(QString cmd, QStringList args)
{
	QStringList output;
	QProcess *process = new QProcess();

	std::cout<<"try to open: "<<cmd.toStdString()<<std::endl;
	process->start(cmd, args/*, QIODevice::ReadOnly*/);

	if (!process->waitForStarted() )
		std::cout<<"process couldn't get opened"<<std::endl;

	// wait for finishing of the process
	process->waitForFinished();
	QTextStream *txt_stream = new QTextStream(process);

	while(!txt_stream->atEnd() )
	{
		std::cout<<"read output: ";
		QString tmp_str = txt_stream->readLine();
		output.append(tmp_str);
		std::cout<<tmp_str.toStdString()<<std::endl;

		if(txt_stream->atEnd() )
		{
			process->close();
			std::cout<<"process finished: "<<std::endl;
			return output;
		}
	}
}

Verfasst: 6. Oktober 2006 10:51
von mephistho
Ist der letzte Post die komplett funktionierende Funktion?

Ich hab mich da ein wenig angelehnt, aber bei mir funktionierts leider nich.
Ich will die Ausgabe aber auch nicht auf der Konsole ausgeben, sondern in eine Datei umleiten. Das könnte ich bei "ping" auch mit ">>", aber ich will später die Zeilen überprüfen und nicht alle in die Datei ausgeben. Nämlich nur die tatsächlichen Antwortzeilen, nicht die Zusammenfassung etc.

Code: Alles auswählen

	QFile *ping_cmd = new QFile(ping_cmd_filename, this);
		
	ping_cmd->open(QIODevice::WriteOnly);
	ping_cmd->write(ping_cmd_str.toLatin1(), strlen(ping_cmd_str.toLatin1()));
	ping_cmd->close();
	
	ping->startDetached(ping_cmd_filename);
	
	QFile *ping_output_file =  new QFile("ping_output.log", this);
	ping_output_file->open(QIODevice::ReadWrite);
	
	ping->waitForFinished();
	QTextStream *ping_output = new QTextStream(ping);	
	
	while(!ping_output->atEnd())
	{
		QString tmp_string = ping_output->readLine();
		ping_output_file->write(tmp_string.toLatin1(), strlen(tmp_string.toLatin1()));
	}

	ping_output_file->close();
Also der Ping startet, schön in nem kleinen Konsolenfenster. Führt einen Ping durch und verschwindet wieder. Die ping_output.log wird auch erstellt, aber bleibt leider leer, 0Byte...

Sieht jemand meinen Fehler?

Und kann er mir bei der Gelegenheit gleich noch verraten, wie ich das Konsolenfenster verstecke? Also wie verhindere ich, dass das Fenster bei jedem Ping (es wird jede Sekunde/Minute/... einer durchgeführt) in der Vordergrund poppt?

Danke & Gruß
meph

Verfasst: 9. Oktober 2006 11:56
von mephistho
Hat keiner ne Idee?

Ich hatte schon vermutet, dass es am OpenMode der Datei liegen könnte. Aber selbst wenn ich da Append nehm, kommt nix in der Datei an. Sie wird nichtmal angerührt, nachdem sie einmal erstellt wurde.

:evil:

Verfasst: 9. Oktober 2006 12:04
von Christian81
1. Warum erzeugst du das komische Batch-File? Schau Dir mal die Doku zu QProcess an!
2. Wie versuchst Du von stdout/stderr zu lesen?? Hier hilft Dir auch die Doku weiter!

Verfasst: 9. Oktober 2006 14:22
von mephistho
1. Weil das auf Anhieb funktioniert hat und der Aufruf von QProcess mit Argumentenlisten nich. Da war ich zu faul mir das zurechtzufummeln.

2. readAllStandardOutput(); ?

Ich raff nich, wie ich das verwenden muss. Ich probier hier rum, aber et will nich ;-/

Wäre für nen weiteren Anstoss dankbar.

Danke!

Verfasst: 9. Oktober 2006 14:30
von Christian81

Verfasst: 9. Oktober 2006 14:34
von mephistho
Hmmm :?:
main.cpp:160: error: 'class QProcess' has no member named 'addArgument'
main.cpp:161: error: 'class QProcess' has no member named 'addArgument'
main.cpp:162: error: 'class QProcess' has no member named 'addArgument'
Qt 4.1.4

Verfasst: 9. Oktober 2006 14:41
von Christian81
Manchmal kann man nur mit den Kopf schütteln... was spricht dagegen einfach mal die DOKU anzuschauen :roll:
http://doc.trolltech.com/4.1/qprocess#details

Verfasst: 9. Oktober 2006 15:10
von mephistho
;)

Ich schüttel schon den ganzen Tag den Kopf über mich selbst. Und in der Doku rumgeschaut hab ich ja auch schon.

Wenn ich das richtig verstehe müsste ich doch mit meinem
ping->readAllStandardOutput() direkt und explizit auf die Standardausgabe meines Prozesses zugreifen, ohne irgendwelche ReadChannels für readLine() o.ä. zu setzen?! Wieso kann ich das denn dann nicht direkt in eine Datei schreiben?

Vielleicht sollte ichs für heute lassen. Ich reg mich nur über mich selbst auf :?

Verfasst: 9. Oktober 2006 15:17
von Christian81
Ich würde wie in der Doku beschrieben den Process erzeugen und dann das Signal readyReadStandardOutput () benutzen um die anliegenden Daten per readAllStandardOutput () auszulesen. Und das dann irgendwo speichern oder was auch immer damit machen.
QProcess ist zwar eine QIODevice, aber ich weiss atm nicht wie man das macht. Ich würde mal sagen man muss erst mit setReadChannelMode() & friends die gewünschten Channels festlegen. Aber bevor man da rumspielt ist readyReadStdout schneller ;-)

Verfasst: 9. Oktober 2006 15:35
von mephistho
Ja, das seh ich genauso.

Dann poste ich mal ein wenig Code, der in meinen anfängerlichen Augen recht sinnvoll aussieht, aber leider nicht den gewünschten Effekt erzielt.

readFromStandardOutput() ist als public SLOT definiert.

Code: Alles auswählen

	ping->startDetached(ping_cmd_filename);
	
	connect(ping, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStandardOutput()));

Code: Alles auswählen

void MyWidget::readFromStandardOutput()
{
	QMessageBox::information(this, "Moep", "Test");

	QString ping_output_filename = QString("ping_output.log");
	QFile *ping_output_file =  new QFile(ping_output_filename, this);
	ping_output_file->open(QIODevice::Append);
	
	ping_output_file->write(ping->readAllStandardOutput());
	
	ping_output_file->close();
}
Mal abgesehen davon, wie schön/unschön das ist, müsste das doch funktionieren oder nich?

Aber er gibt z.B. nichtmal die MsgBox aus, wenn der Prozess gestartet und Daten ausgespuckt werden.

Danke für deine Geduld ;)