Seite 1 von 2

Shell Scripte via QT aufrufen

Verfasst: 5. Juli 2006 10:49
von dauda
Hallo!

Ich verfolge im Moment eine sicherlich nicht sehr schöne Art und Weise, ein QT-Projekt zu erstellen.
Ich habe folgendes vor:

Ich habe bisher ein Fenster programmiert (Main Window) und mit verschiedenen Buttons belegt. Diese Buttons solllen ein C-Programm aufrufen.
Diese C-Programme sind natürlich nicht in die QT-Programmierung implementiert. Diese C-Programme werden stattdessen über Scripte extern aufgerufen. Genau an dieser Stelle liegt das Problem. Der Aufruf der Programm sieht so aus, dass die Konsole kurz aufflackert und sofort wieder geschlossen wird. Die C - Programme, sofern bei diesen keine weitere Eingabe notwendig ist, werden problemlos ausgeführt, dagegen werden C-Programme, die weitere Eingaben verlangen, nicht ausgeführt.
Woran kann das liegen?

Sicherlich werden sich viele User fragen, warum ich auf diesen Weg die QT Programmierung nutze, nun ich habe zuvor ein Programm geschrieben und erst jetzt hat sich ergeben, dass ich diesem Programm noch eine grafische Oberfläche geben möchte, daher nun diese Umsetzung.

Hier nun noch de Quelltext mit einem Beispielscript.

***************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** Qt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/


void MainForm::fileNew()
{

//not yet associated with a function

}


void MainForm::fileOpen()
{

//not yet associated with a function

}


void MainForm::fileSave()
{

//not yet associated with a function

}


void MainForm::fileSaveAs()
{

//not yet associated with a function

}


void MainForm::fileExit()
{

//not yet associated with a function

}




void MainForm::editCut()
{

//not yet associated with a function

}


void MainForm::editCopy()
{

//not yet associated with a function

}


void MainForm::editPaste()
{

//not yet associated with a function

}


void MainForm::editFind()
{

//not yet associated with a function

}


void MainForm::helpIndex()
{

//not yet associated with a function

}


void MainForm::helpContents()
{

//not yet associated with a function

}


void MainForm::helpAbout()
{

//not yet associated with a function

}


void MainForm::newSysConfig()
{

system("xterm -e .startzugriff.sh");

}


void MainForm::newIpScan()
{

system("xterm -e .startipscan.sh");

}


void MainForm::newIplist()
{

system("xterm -e .showiplist.sh");

}


void MainForm::newKeyClient()
{

//Systemaufruf von Schlüsselinstall!

}


void MainForm::newPing()
{

system("xterm");
system("xterm -e .testscript.sh");

}


void MainForm::newBing()
{

system("xterm");

}


void MainForm::newNetio()
{

//Systemaufruf von NETIO

}


void MainForm::newIperf()
{

//Systemaufruf von IPERF

}


void MainForm::newIperfClient()
{

//Systemaufruf von Iperf-Client

}


void MainForm::newNetioClient()
{

//Systemaufruf von Netio-Client

}



void MainForm::newFileTransfer()
{

//Systemaufruf von Filetransfer

}

###############################################
testscript.sh

#!/bin/sh


./testfile

sleep 3h


###############################################
testfile.c

#include<stdio.h>

int main()
{

printf("Testausgabe");

}

Anmerkung:

Rufe ich die Scripte über die Bash auf, so werden die Scripte auch in dieser ausgeführt. Rufe ich die Scripte unter xterm auf, so kommt es zu Fehlern. Mein Ziel wäre es, dass sich die Kommandozeile erst öffnet und nicht vorher geöffnet sein muss.

Verfasst: 5. Juli 2006 11:28
von patrik08
Du musst auf die ****.pro datei achten..

wenn auf der erste zeile
TEMPLATE = app console
ist dann ist dieses programm nur auf der console....

wenn ...

TEMPLATE = app
ist dann kommt dieses programm im X11
dann gibt es noch
CONFIG += qt warn_on staticlib
TEMPLATE = lib

die eine statische libs baut....

sicher gibt es noch mehr moeglichkeiten doch mit diese 3 macht mann bereist viel...

um deine bash script zu starten suche im forum nach qprocess oder
http://qtforum.de/forum/viewtopic.php?t=2366 mac beispiel... mac beist nicht ist fast wie linux...

Verfasst: 5. Juli 2006 11:40
von dauda
Vielen Dank für diese schnelle Antwort, es gibt aber ein Problem.

Ich arbeite mit Suse Linux 10.0 und hier mit dem Qt Designer, der mir nur die Grafik anzeigt, wenn ich auf das File *****.pro klicke. Ich weiß nicht, ob du das Programm kennst.
Ich kann daher nichts einstellen.

Vielleicht weißt du eine Antwort?

Wenn, wie genau sieht das für mein Beispiel aus?

Verfasst: 5. Juli 2006 11:44
von dauda
Da File sieht so aus:

Wo muss ich jetzt etwas ändern??

TEMPLATE = app
LANGUAGE = C++

CONFIG += qt warn_on release

SOURCES += main.cpp

FORMS = mainform.ui

IMAGES = images/filenew \
images/fileopen \
images/filesave \
images/print \
images/undo \
images/redo \
images/editcut \
images/editcopy \
images/editpaste \
images/searchfind \
images/nis_client.png \
images/stock_form-table-control.png \
images/key_ok.png \
images/ping.png \
images/bing.png \
images/network_advanced.png \
images/network_advanced56.png \
images/netioclient.png \
images/iperfclient.png \
images/kdar_create.png \
images/beowulf_01.png \
images/network_local.png

unix {
UI_DIR = .ui
MOC_DIR = .moc
OBJECTS_DIR = .obj
}

Verfasst: 5. Juli 2006 12:00
von patrik08
dass pro file ist richtig und es arbeitet im X11 modus...
gehe zu deinem ordner cd xx

qmake & make
fehler lesen....

und wenn deine scripte nicht gehen

system("/vollen/pfad/showiplist.sh");
oder
system("./showiplist.sh"); ( ./script nicht .script ) von der applikation aus gesehen ./xxxxxx

oder ("~/bin/xxx.sh") vom user home weg.. xterm ist nicht notig....

Verfasst: 5. Juli 2006 12:04
von dauda
so sieht die Fehlermeldung aus:

/usr/lib/qt3/bin/uic mainform.ui -i mainform.h -o .ui/mainform.cpp
g++ -c -pipe -O2 -march=i586 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -Wall -W -O2 -march=i586 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -DQT_NO_DEBUG -DQT_SHARED -DQT_TABLET_SUPPORT -DQT_THREAD_SUPPORT -I/usr/lib/qt3/mkspecs/default -I. -I/usr/include -I/usr/lib/qt3/include -I.ui/ -I. -I.moc/ -o .obj/mainform.o .ui/mainform.cpp
/usr/lib/qt3/include/qtooltip.h:86: warning: ‘class QToolTip’ has virtual functions but non-virtual destructor
g++ -o clusterscan .obj/main.o .obj/mainform.o .obj/qmake_image_collection.o .obj/moc_mainform.o -L/usr/lib/ -L/usr/lib/qt3/lib/ -L/usr/X11R6/lib/ -lqt-mt -lXext -lX11 -lm


Ich weiß nicht ob du damit etwas anfangen kannst.
Das mit dem Pfad werde ich versuchen. Wie aber ist es zu erklären, dass das Programm Scripte ausführt, die keiner Eingabe bedürfen und dass es Probleme macht bei Scripten, wo Benutzereingaben erforderlich sind? Ich meine, das zeigt doch eigentlich, dass die Pfade stimmen müssen und das das Script korrekt aufgerufen wird, oder?

Verfasst: 5. Juli 2006 12:45
von patrik08
dass programm solte in deinen ordner liegen ... es befindet sich keine error meldungen....

Verfasst: 5. Juli 2006 12:52
von dauda
jepp liegt es und es ist auch ausführbar....dabei tritt ja dann dieser eigenartige Fehler auf....

Also man könnte sagen, sobald dieses Script ein C-Programm startet, dass eine Benutzerabfrage verlangt, kommt es zu Problemen.

Ich danke dir trotzdem für deine Hilfe, auch wenn ich jetzt wieder am Anfang stehe.

Gruß in die Schweiz!

Verfasst: 5. Juli 2006 13:03
von patrik08
dauda hat geschrieben:jepp liegt es und es ist auch ausführbar....dabei tritt ja dann dieser eigenartige Fehler auf....

Also man könnte sagen, sobald dieses Script ein C-Programm startet, dass eine Benutzerabfrage verlangt, kommt es zu Problemen.

Dann schreibe scripte wo man dass password uebergeben kann.

./script.sh -p pass -u user -h host

ecc....

Verfasst: 5. Juli 2006 15:33
von dauda
achso, nee....ich meinte damit, dass ich al Benutzer Daten eingeben muss, das hatte ich wohl falsch formuliert....es hat also nichts mit Benutzerabfragen zu tun, sondern in den Scripten wird zum Beispiel verlangt, eine IP einzugeben....solche Sachen meinte ich, und da kommt es auch zu Problemen....

Verfasst: 5. Juli 2006 16:06
von ChMaster
servus,

die variante von patrik08 funktioniert, wenn du mal in die Doku schaust,
findest du QCoreApplication und QProcess, lies mal durch .... dir wird
bestimmt was auffallen.

hier ein kleines beispiel ....

Code: Alles auswählen

QStringList args;
QString shScriptFile, workDir;

workDir = QCoreApplication::applicationDirPath();
shScriptFile = QCoreApplication::applicationDirPath();
shScriptFile.append( "/xxx.sh" )

QProcess *p = new QProcess(this);

args.append( shScriptFile);
args.append( "-ip" );
args.append( "127.0.0.1" );

p->setWorkingDirectory( workDir  );
p->start( "sh", args );

while ( p->waitForFinished() ) {
    QString output = p->readAll();
}

workDir = "";
shSrciptFile = "";
args.clear();
delete p;
nen bisschen unsauber, aber hilft auf die schnelle ;)

Verfasst: 5. Juli 2006 16:26
von dauda
Oh vielen Dank, aber ich habe da mal eine Frage:

Welche Variante von Patrik meinst du denn?

Hast du dir das, was davor geschrieben wurde, durchgelesen?

Ich habe das Problem, dass ich, wenn ich per Bash - Script eine C-Funktion aufrufe, er diese nur fehlerhaft ausführt, weil er keine Möglichkeit lässt, Eingaben zu tätigen.
Es öffnet das Fenster scheinbar nur für einen sekundenbruchteil und das war es dann. Dieser Fehler tritt nur auf, wenn die C-Programme eine Abfrage an den User starten (diese Abfrage sieht so aus, dass man zumTeil IP-Adressen , Namen etc. eingeben muss). Verlangt das C-Programm keine EIngabe, sondern sollen es nur irgendwelche Sachen selbstständig ändern, dann läuft es ohne Probleme.

Das was patrik mir geraten hatte, habe ich alles umgesetzt, der Charakteristik des Fehlers zeigt mir aber, dass es im Grund ja nicht an der EIngabeform liegen muss, also ich meine damit die Art und Weise, wie das jeweilige Script aufgerufen wird. Zudem habe ich schon alle Varianten getestet.

Ich muss aber auch zugeben, dass ich nicht wirklich Ahnung habe. Daher sage mir doch bitte, was ich mit deinem Code anfangen kann und woher ggf. hingehört, falls ich den implementieren muss, ob er unsauber ist oder nicht, das ist latte....

Abschliessend bitte ich um Verständnis, da ich wohl sicher in euren Augen etwas schwerfällig bin, aber eigentlich wollte ich doch nur eine grafische Oberfläche zu einem bestehenden Programm schreiben ;-) .

Gruß

Verfasst: 5. Juli 2006 16:38
von ChMaster
servus,

ich meine in diesem fall alle varianten :P

...

so wie ich dich verstanden habe, schreibst du eine GUI die ein externes
programm aufrufen soll und du gerne dem externen programm ein paar
parameter übergeben möchtest und die ausgabe evtl auch noch lesen
willst? (alles richig?)

ist dies der fall, kommt das stückchen code, was ich vorhin gepostet habe,
in den ereignisclick deines buttons .... (signal/slot handling anschauen)

ps.:
der code ausschnitt basiert auf Qt4.
Qt3 user sterben aus, habe ich mir sagen lassen :P

Verfasst: 5. Juli 2006 16:50
von dauda
Also vielen Dank!

Und es war nicht alles richtig.

Ich will ein externes Programm starten.

Das will ich erreichen, indem ich ein Button drücke.

Dieses externe Programm arbeitet selbstständig und ich übergebe ihm nichts dirket, eigentlich übergebe ich ihm überhaupt nichts. Ich will nur das Programm starten. Weil ich das Programm nicht per C++ geschrieben habe, wollte ich Scripte nutzen, die mein C-Programm aufrufen.

Diese Abfragen starten nachher die C-Programme. Sie bekommen nichts übergeben und ja arbeiten selbstständig.

Lass mich mal raten. Auf Suse Linux 10.0 läuft doch garantiert Qt 3 oder???

Kannst du nun mit den Daten etwas anfangen???

Verfasst: 5. Juli 2006 16:52
von dauda
Dem externen Programm werden keine Parameter übergeben.

Kurios an der Sache ist:

Verlangt das externe Programm eine Eingabe, so kommt es zum Fehler.

Verlangt es keine Eingabe und führt etwas aus, wo der Benutzer nicht eingreifen muss, dann kommt es zu keinem Fehler.

Alles klar?!? ;-)