Sie sind nicht angemeldet.

  • »flosch« ist der Autor dieses Themas

Beiträge: 4

Registrierungsdatum: 24.04.2012

  • Nachricht senden

1

01.10.2012, 16:40

Aus einem Programm ein zweites Programm starten ohne auf die Beendigung des neu gestarteten Programms zu warten.

Ja, ich arbeite gerade mit einem Webserver, und eigentlich will ich "nur" ein Script starten, dass dann im eigenen Prozess laufen soll, und bei dem mein Hauptprogramm (der Webserver) nicht auf die Beendigung wartet sondern gleich mit anderen Aufgaben weitermacht.

Info dazu: es gibt einen "Treiber" über den dann die Kommunikation vom Script zum Webserver stattfindet, deshalb kann (und soll) das Skript auch unabhängig laufen.

Bislang habe ich folgende Schritte erfolglos getestet:

1. "System(..)" mit "nohup" bzw. "&" am Ende. Rückkehr zum Hauptprogram erst am Ende der Ausführung des Scriptes.
2. Erstellen eines scriptes mit "nohup" bzw. "&" und Aufrufen desselben. Selbes Verhalten wie vorher.
3. Benutzen von "fork" und "exec". Danach hatte ich eine doppelte Webseite. Wirklich laufen tat aber damit auch nichts.

Randdaten: das ganze läuft auf einem Embedded-Linux, und mein Programm/Webserver läuft als Daemon.

Das Problem ist, dass ich eher von der Windows-Seite komme, und da gibt es den Befehl "CreateProcess", damit kann ich einen neuen Prozess erzeugen, und der kann dann machen was er will. Unter Linux scheint das hingegen ein Problem darzustellen?!

Jetzt probiere ich gleich nochmal ein paar Exec()-Variationen aus, verspreche mir allerdings nicht allzuviel davon. Außerdem starte ich gleich mal einen Suchlauf bei Google mit den Worten "CreateProcess Äquivalent in Linux", parallel dazu versuche ich es einfach mal hier im Forum.

Vielleicht weiß ja einer was ich falsch mache oder wie ich ein Programm dazu bekomme unabhängig vom Aufrufer zu laufen?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »flosch« (08.10.2012, 10:12) aus folgendem Grund: Problem gelöst.


2

01.10.2012, 17:23

eigentlich will ich "nur" ein Script starten
Du willst das Script starten oder der Webserver soll es starten?
Wenn letzteres, wie soll er es starten, als CGI über ein Formular oder...?
Was für ein Webserver ist es?
In welcher Sprache ist das Script geschrieben?

es gibt einen "Treiber" über den dann die Kommunikation vom Script zum Webserver stattfindet
Das würde mich dann auch noch interessieren, wie das abläuft.
In God They Trust. All Others They Monitor.

  • »maettu« ist männlich

Beiträge: 3 177

Registrierungsdatum: 14.09.2005

Wohnort: Schweiz

Derivat: Xubuntu

Version: 14.04 (Trusty Tahr)

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

3

01.10.2012, 17:39

Zitat

ein Script starten, dass dann im eigenen Prozess laufen soll,
heisst das ein Child-Prozess, oder brauchst du einen Thread? Was muss dieses Script dann machen?
Thread-Kommunikation ist glaube ich nicht so ganz einfach.

.not

User

Beiträge: 730

Registrierungsdatum: 28.07.2011

Derivat: Kein Ubuntu-Derivat

Version: keine Ubuntu-Version

Architektur: 64-Bit PC

Desktop: anderer

Andere Distribution: Mac OSX, FreeBSD, Debian Jessie

  • Nachricht senden

4

01.10.2012, 18:37

Sorry für Off-Topic, aber: Geiler Threadtitel. :D

Zitat

Weiss jemand wo man dieses Zeug, welches Poettering raucht, kaufen kann? Und brennt das dann auch mit nem normalen Feuerzeug? Oder brauch ich da jointd dazu, um den Rauch zu erzeugen?

  • »flosch« ist der Autor dieses Themas

Beiträge: 4

Registrierungsdatum: 24.04.2012

  • Nachricht senden

5

01.10.2012, 19:14

Ja, ein bisschen Hintergrund sollte ich wohl liefern, daher werde ich mal die Themen der Reihe nach anschneiden:

Es handelt sich um einen KLone-Webserver der auf einem Embedded-Linusx läuft (Microblaze-CPU, Kernel-Version weiß ich gerade aus dem Kopf nicht).

Der Webserver soll, nachdem er eine Datei hochgeladen hat, auf besagtem Linux ein Script (lokal) starten (antriggern), und dann weiterlaufen. Das Script soll dann parallel zum Webserver laufen, seine Sachen erledigen und irgendwann fertig sein.
In der Zeit läuft auf dem Client ein Javascript das sekündlich den Status vom Webserver abruft (also muss der ansprechbar sein und darf nicht darauf warten, dass besagtes Script oben fertig wird...), und irgendwann reagiert das Javascript/Client dann ("Update fettisch, jetzt bitte neustarten" oder so).

Das Script selber ist ein Shellscript, der Treiber ist ein selbstgeschriebener Treiber der quasi ein Datenfeld beim Lesen zurückliefert und über eine Offset/Data-Struktur beschrieben werden kann. Was da im einzelnen passiert ist wohl egal, im Prinzip läuft es auf eine Datei hinaus die auf einer Seite (binär) beschrieben und auf der anderen Seite (binär) gelesen wird. Zugriffe laufen hier asynchron, das sollte also nicht das Problem sein.

Child/Thread: am liebsten wäre es mir, ich könnte einen eigenen Prozess/Thread mit dem Script starten. Bein Windows gibts CreateProcess, allerdings fand ich bei der Suche "CreateProcess" und "Linux" eigentlich nur Referenzen auf fork()/exec().

Falls mir jemand Hinweise zu Threadprogrammierung außerhalb fork/exec geben könnte wäre ich dankbar.

Wobei meine Vermutung mittlerweile dahin geht, dass beim Erzeugen der Anwendung irgendwelche Flags gesetzt sind die verhindern, dass der Server asynchrone (ich nenn die jetzt mal so) Ausführungen von Scripts zulässt, denn die gleichen Scripts laufen halt in der Shell ohne Probleme?!

  • »maettu« ist männlich

Beiträge: 3 177

Registrierungsdatum: 14.09.2005

Wohnort: Schweiz

Derivat: Xubuntu

Version: 14.04 (Trusty Tahr)

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

6

01.10.2012, 20:25

Zitat

In der Zeit läuft auf dem Client ein Javascript das sekündlich den
Status vom Webserver abruft (also muss der ansprechbar sein und darf
nicht darauf warten, dass besagtes Script oben fertig wird...),
Also Polling mit HIlfe von Javascript.
Was macht der Webserver während dem das Skript läuft? Nichts ausser Antworten auf die Polling-Anfragen des Java-Skript-Clients?

Du könntest doch einfach wenn dein Skript fertig ist mit der Verarbeitung, eine andere HTML-Seite laden/anzeigen auf dem Webserver.

PS: Du kommunizierst bei deiner Beschreibung immer mit dem Webserver-Prozess, also musst du eine Kommunikation zwischen dem Webserver-Prozess und deinem Skript herstellen.
Primitive Lösung ist du änderst via Skript einfach die "Index.html" im Rootverzeichnis des Webservers, das Ganze ist dann nicht sehr intelligent besonders bei Mehreren Verbindungen zum Webserver...

PPS: Vielleicht wäre ein CGI-Skript auch nicht so falsch...

7

02.10.2012, 01:23

Ein wenig Hintergrundbeleuchtung hilft wirklich etwas weiter :)
Trotzdem hänge ich am Anfang fest:
ein Script starten, dass dann im eigenen Prozess laufen soll, und bei dem mein Hauptprogramm (der Webserver) nicht auf die Beendigung wartet
Ich hab die KLone-Seite überflogen und kenne mich mit dem Ding erstmal noch nicht aus. Aber bist du sicher, daß der Server wirklich stehen bleibt und auf das Ende des Scripts wartet, und nicht nur auf irgendeine Rückmeldung von diesem?
Der Grundgedanke beim Aufruf externer Programme ist ja meistens die Erzeugung dynamischer Inhalte und auf die muß er dann natürlich warten. Dann wäre er mit einem simplen "OK" auch schon zufrieden und könnte tun, was immer von ihm verlangt wird, während das Script noch ewig weiterlaufen kann.
In God They Trust. All Others They Monitor.

  • »flosch« ist der Autor dieses Themas

Beiträge: 4

Registrierungsdatum: 24.04.2012

  • Nachricht senden

8

02.10.2012, 10:36

Zitat

Also Polling mit HIlfe von Javascript.
Genau. Wobei da halt im Sekundentakt eine "Webseite" aufgerufen wird, die den aktuellen Status ausliest und an meine Wartende Seite weiterleitet. Das Problem ist, dass ich halt während der Ausführunf des Scriptes den Zustand des Updates (was das Script halt ausführt) darstellen will, sonst habe ich halt eine Webseite die n Minuten hängt und wo man im Zweifel nicht weiß ob da noch was läuft oder jetzt der Webserver/das Board/WattWeissIsch abgestürzt ist.

Zitat

Was macht der Webserver während dem das Skript läuft? Nichts ausser Antworten auf die Polling-Anfragen des Java-Skript-Clients?
Genau, wobei der Server aber schon beim Aufbau der Polling-Seite hängt. Beim KLone kann ich halt mein Scripting direkt in der Webseite ausführen, d.h. nach dem Upload der Datei wird die neue Seite aufgerufen, diese startet dann das Shell-Script (soll es zumindest) und soll im zweiten Schritt dann sekündlich das Status-Polling machen.

Wobei ich jetzt gerade die Idee habe, dass ich das Aufrufen des Skriptes vielleicht auch in eine separate Seite auslagere die ich aufrufe... hmm.
PS: Du kommunizierst bei deiner Beschreibung immer mit dem Webserver-Prozess, also musst du eine Kommunikation zwischen dem Webserver-Prozess und deinem Skript herstellen.
Richtig.
Primitive Lösung ist du änderst via Skript einfach die "Index.html" im Rootverzeichnis des Webservers, das Ganze ist dann nicht sehr intelligent besonders bei Mehreren Verbindungen zum Webserver...
Wie soll das gehen? Außerdem ist es doch egal ob ich meine Seite XYZ.html per Javascript anpasse oder die Index.html?
PPS: Vielleicht wäre ein CGI-Skript auch nicht so falsch...
Im Prinzip mache ich genau das, wobei ich halt statt CGI halt den Onboard-C-Code des Servers benutze.
Ich hab die KLone-Seite überflogen und kenne mich mit dem Ding erstmal noch nicht aus. Aber bist du sicher, daß der Server wirklich stehen bleibt und auf das Ende des Scripts wartet, und nicht nur auf irgendeine Rückmeldung von diesem?
Ja, ich habe nämlich gerade die Info von den KLone-Leuten bekommen, dass der Aufruf von "System()" immer "blocking" ist. Das haben die wohl so eingebaut.
Der Grundgedanke beim Aufruf externer Programme ist ja meistens die Erzeugung dynamischer Inhalte und auf die muß er dann natürlich warten. Dann wäre er mit einem simplen "OK" auch schon zufrieden und könnte tun, was immer von ihm verlangt wird, während das Script noch ewig weiterlaufen kann.
Ja, nur mein Grundgedanke in dem Fall ist: Shellscript asynchron starten um das Update (der Boardfirmware) laufen zu lassen, derweil soll die Webseite warten, und in regelmäßigen Abständen den Status zurückliefern.

An sich erscheint mir das nicht unbedingt als Spezialanwendung, es gibt sicherlich reichlich Ansätze wo der Gedanke ist: Starte was, bearbeite das auf dem Server und gib mir in Regelmäßigen Abständen den Zwischenstand.

Aber ich habe, wie oben berichtet, gerade von den KLone-Leute ein Example mit fork/exec bekommen, das probiere ich gleich mal aus. Fall nicht probiere ich dann mal Plan B: das Script über eine weitere Webseite triggern.

  • »maettu« ist männlich

Beiträge: 3 177

Registrierungsdatum: 14.09.2005

Wohnort: Schweiz

Derivat: Xubuntu

Version: 14.04 (Trusty Tahr)

Architektur: 64-Bit PC

Desktop: XFCE

  • Nachricht senden

9

02.10.2012, 11:51

Zitat

Wie soll das gehen? Außerdem ist es doch egal ob ich meine Seite XYZ.html per Javascript anpasse oder die Index.html?
Du weisst das Javascript im Browser des Clients läuft? Die Idee mit der Index.html anzupassen ist via Shellskript eine Datei überschreiben, das läuft dann direkt auf deinem Webserver. Ist aber auch mehr oder weniger ein Quick-Dirty-Hack.

Zitat

Starte was, bearbeite das auf dem Server und gib mir in Regelmäßigen Abständen den Zwischenstand.
Du musst im Prinzip ja gar nichts Asynchrones mit mehreren Prozessen machen. Von dem her ist Blockierend ja sogar gewünscht oder?

10

02.10.2012, 12:05

An sich erscheint mir das nicht unbedingt als Spezialanwendung, es gibt sicherlich reichlich Ansätze wo der Gedanke ist: Starte was, bearbeite das auf dem Server und gib mir in Regelmäßigen Abständen den Zwischenstand.
Der Vorgang selbst ist sicher keine Spezialanwendung. Der Server kann ja jederzeit die jeweils letzte in HTML eingebettete Ausgabe des Scripts (oder eben des "Treibers" *) ausliefern, wenn der Client danach fragt. Aber das machst du ja sowieso per JS. Das Script könnte auch eine "refresh"-Direktive in die Seite einbauen, so daß sie der Client auch ohne JS neu laden würde. Alles schon dagewesen, nur daß die gängigen Webserver eben normalerweise nicht stehen bleiben und warten. So gesehen ist also doch eine Spezialanwendung mit im Spiel, aber damit ist nicht die Methode gemeint :)
Bin gespannt, mit was für einer Lösung die Entwickler dafür aufwarten können. Lass uns wissen, bitte.

*) wobei ich mich gerade frage, wie der Server den Ausgabekanal des Treibers von selbst findet. Da wird wohl auch das Script als Zwischenstation herhalten müssen. Aber in dem Punkt wirst du schon wissen, was du machst.
In God They Trust. All Others They Monitor.

  • »flosch« ist der Autor dieses Themas

Beiträge: 4

Registrierungsdatum: 24.04.2012

  • Nachricht senden

11

08.10.2012, 10:12

So, ich habe es geschafft. Ich musste doch "fork()" und "exec()" nehmen, das Problem lag allerdings u.a. bei der etwas eigentümlichen Art und Weise wie man, zumindest auf dem benutzten Embedded-Linux, exec[v]() aufruft, da parameter 0 (arg[0]) eben nicht der erste Parameter ist, sondern den Name des Aufzurufenden Programms beinhalten muss! Vielleicht geht da auch ein Dummy, keine Ahnung ob das funktioniert, NULL darf es auf jeden Fall nicht sein! :)

Außerdem sollen zumindest beim KLone wohl beim Childprozess die offenen Handles geschlossen werden!?

Refresh: der ist für mich keine Option, da die komplette Webseite dann neu geladen wird und das mitunter doof aussieht (und der dann meistens an den Anfang der Seite springt und die Bedienung darunter leiden kann). JS und "innerHTML" ist da die bessere Lösung, da ich da gezielt Textelemente (z.B. Uhrzeit) ändern kann.

Server: da gibt es keinen "Ausgabekanal". Der Treiber ist einfach so ausgelegt, dass beim Öffnen des Treibers ein interner Zähler auf "0" gesetzt wird, beim "read()" wird dann ab Zähler (also 0) bis X ein Speicherbereich ausgelesen der mit der HW verdraht ist (vereinfach gesagt), dann wird der Treiber wieder geschlossen, so bekommt der Server seine Informationen.

Serverintern werden dann die Daten noch in eine Struktur kopiert, da ein "int data[1234];" immer etwas schwierig zu habdhaben ist, aber das sind dann ja schon Implementationsdetails.

12

08.10.2012, 13:34

das Problem lag allerdings u.a. bei der etwas eigentümlichen Art und Weise wie man, zumindest auf dem benutzten Embedded-Linux, exec[v]() aufruft, da parameter 0 (arg[0]) eben nicht der erste Parameter ist, sondern den Name des Aufzurufenden Programms
Das ist aber bei meinem Linux hier genauso eigentümlich. Aus der man-page:

Zitat

int execv(const char *path, char *const argv[]);
The execv() and execvp() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed.
In God They Trust. All Others They Monitor.

Beiträge: 235

Registrierungsdatum: 23.06.2009

Wohnort: Wolke 7

Architektur: 64-Bit PC

Desktop: GNOME 3.0

Andere Distribution: Debian 7.0 wheezy

  • Nachricht senden

13

16.11.2012, 01:05

das gleiche hab ich vorn paar tage auch gesucht und folgendes entdeckt :


http://wiki.ubuntuusers.de/Skripte/Autostart-Patch