Forum: PC-Programmierung Konsole/Shell nach dem Programmstart schliessen


von dd4 (Gast)


Lesenswert?

Hallo.

Ich habe ein C-Programm, dass eine Logfile öffnet und in der Uptime des 
OS Daten speichert.

Nach dem Programmstart ist die Shell die ganze Zeit geöffnet.

Schöner wäre es, wenn sie einfach schliesst, sobald das Programm einmal 
läuft. Aber wie mache ich das?

Innerhalb des Programms einen Prozess starten und zum Ende hin einfach 
system(exit)?

von dd4 (Gast)


Lesenswert?

Ich schrieb:

>Innerhalb des Programms einen Prozess starten und zum Ende hin einfach
>system(exit)?

...einen Dämonprozess...

von Sheeva P. (sheevaplug)


Lesenswert?

dd4 schrieb:
> Ich schrieb:
>
>>Innerhalb des Programms einen Prozess starten und zum Ende hin einfach
>>system(exit)?
>
> ...einen Dämonprozess...

...oder ein "systemd user defined service".

von Daniel A. (daniel-a)


Lesenswert?

Sheeva P. schrieb:
> dd4 schrieb:
>> Ich schrieb:
>>
>>>Innerhalb des Programms einen Prozess starten und zum Ende hin einfach
>>>system(exit)?
>>
>> ...einen Dämonprozess...
>
> ...oder ein "systemd user defined service".

Ich vermute das hier von Windows die rede ist, weil Programme unter 
Linux keine shell öffnen, wenn man diese nicht in einer startet. Wenn 
man die Programme in einer schell startet kann man mit 'nohub 
programmname&exit' das Programm als background job öffnen und die Schell 
schliessen. Das kann man auch im Programm machen, indem man fork nutzt 
und stdin+stdout schliesst. Damit unter windows keine Konsole geöffnet 
wird. Falls die shell von einer .desktop datei erzeugt wird, einfach die 
Option aus dieser entfernen.
Unter windows kann man entweder dem Kompiler eine Option mitgeben, oder 
_tmain bzw. WinMain statt main benutzen.

von dd4 (Gast)


Lesenswert?

Sheeva Plug schrieb:

>...oder ein "systemd user defined service".

Bietet auch eine c api an, müsste man sich aber einarbeiten. Das müsste 
man auf dem "klassischen" Wege mit einem Dämonprozess natürlich auch, 
sofern er funktionieren würde.

Der Dienst sollte aus dem Programm heraus gestartet werden. Ich denke 
mal Dein Hinweis mit dem "systemd user defined service" bezog sich auf 
eine schnelle Lösung in der Shell mittels systemctl, richtig?

von dd4 (Gast)


Lesenswert?

Hallo Daniel,

ich nutze Linux. Aber wegen dem Aspekt der Portaibilität sollte das 
ganze auch auf Windows laufen, dass ist schon richtig.

von dd4 (Gast)


Lesenswert?

Daniel Albrecht schrieb:

>Ich vermute das hier von Windows die rede ist, weil Programme unter
>Linux keine shell öffnen, wenn man diese nicht in einer startet.

Letzteres trifft zu. Ich starte es in der Shell.

von Kaj (Gast)


Lesenswert?

Entweder über systemd starten oder im autostart eintragen.

systemd:
https://wiki.archlinux.org/index.php/Systemd

Autostart unter Plasma5:
Systemeinstellungen -> Starten und Beenden -> Autostart -> Programm 
hinzufügen

Bei Windows kannst du es ja ebenfalls einfach in den Autostart legen.

Oder hab ich das Problem jetzt nicht verstanden? :-/

von dd4 (Gast)


Lesenswert?

Kaj schrieb:

> Entweder über systemd starten oder im autostart eintragen.
> Oder hab ich das Problem jetzt nicht verstanden? :-/

Überlesen trifft es eher :=)

>>Der Dienst sollte aus dem Programm heraus gestartet werden.

Deshalb ja auch meine Eingangsfrage in Zusammenhang mit einem 
Dämonprozess, welcher im Hintergrund läuft, ohne das ihm zwangsläufig 
eine Shell zugeordnet ist.

von daemonize (Gast)


Lesenswert?


von dd4 (Gast)


Lesenswert?

Ok, verstehe wo mein Fehler liegt.

Da wir im Forum "Programmierung" sind, habe ich implizit vorausgesetzt, 
dass ich diesen Programmpart selbst programmieren will, wenn ich 
schreibe, dass der Dienst aus dem Programm heraus aufgerufen werden 
soll.

Bei den ganzen Hinweisen -vielen Dank hierfür- gehe ich mal davon aus, 
dass ich mit einem Dämonprozess schon auf der richtigen Färte war, wenn 
ich mir Eure Antworten so ansehe.

von dd4 (Gast)


Lesenswert?

Lösung:

1. fork()
2. setsid()
3. SIGHUP ignorieren
4. fork()
5. chdir() chroot() (optional)
6. umask()
7. close()
8. openlog()

Nach soetwas hatte ich gesucht.

von Peter II (Gast)


Lesenswert?

dd4 schrieb:
> Lösung:

naja, das ist wirklich nur ein Zeiten vor systemd notwendig. Auch Linux 
entwickelt sich weiter.

von Sheeva P. (sheevaplug)


Lesenswert?

dd4 schrieb:
> Sheeva Plug schrieb:
>
>>...oder ein "systemd user defined service".
>
> Bietet auch eine c api an, müsste man sich aber einarbeiten. Das müsste
> man auf dem "klassischen" Wege mit einem Dämonprozess natürlich auch,
> sofern er funktionieren würde.
>
> Der Dienst sollte aus dem Programm heraus gestartet werden. Ich denke
> mal Dein Hinweis mit dem "systemd user defined service" bezog sich auf
> eine schnelle Lösung in der Shell mittels systemctl, richtig?

Mein Hinweis bezieht sich auf eine elegante Lösung mit einem Unitfile in 
~/.config/systemd/user/, das dann mit "systemctl --user" verwaltet wird. 
Dabei kann man sich die C API und das Daemonizing ganz ersparen und das 
Logging und die Beachtung von Abhängigkeiten sind auch schon drin. ;-)

von dd4 (Gast)


Lesenswert?

Sheeva Plug schrieb:

> das dann mit "systemctl --user" verwaltet wird.

Sag ich ja.

>>bezog sich auf eine schnelle Lösung in der Shell mittels systemctl, >>richtig?

>Dabei kann man sich die C API und das Daemonizing ganz ersparen und das
>Logging und die Beachtung von Abhängigkeiten sind auch schon drin. ;-)

Sicher, eine Zeile in der Shell würde das "Problem" lösen, aber nochmal, 
da wir hier im Forum Programmierung sind, sollten auch solche 
Lösungsansätze zum Tragen kommen.

Ich versuche das nicht in C umzusetzen, weil ich Langeweile habe oder es 
gerne unnötig verkomplizieren möchte, sondern weil ich etwas neues dazu 
lernen möchte.

Ich war Anfangs unsicher, ob ich mit den Dämonenprozessen überhaupt auf 
der richtigen thematischen Seite bin.

>>Innerhalb des Programms einen Prozess starten und zum Ende hin einfach
>>system(exit)?

Abgesehen von dem Quatsch mit dem system(exit), weiss ich nun, dass die 
grobe Denke schonmal richtig war.

>1. fork()
>2. setsid()
>3. SIGHUP ignorieren
>4. fork()
>5. chdir() chroot() (optional)
>6. umask()
>7. close()
>8. openlog()

Und so groß ist der Programmieraufwand bei dieser Lösung auch nicht, 
aber lerntechnisch ergibt sich einiges für Neulinge, die sich mit diesem 
Thema bislang nicht beschäftigt haben, finde ich.

von Sheeva P. (sheevaplug)


Lesenswert?

dd4 schrieb:
> Sheeva Plug schrieb:
>>Dabei kann man sich die C API und das Daemonizing ganz ersparen und das
>>Logging und die Beachtung von Abhängigkeiten sind auch schon drin. ;-)
>
> Sicher, eine Zeile in der Shell würde das "Problem" lösen, aber nochmal,
> da wir hier im Forum Programmierung sind, sollten auch solche
> Lösungsansätze zum Tragen kommen.

Bei "eine Zeile" oder "eine schnelle Lösung in der Shell" würde ich 
nicht an systemd, sondern an ganz einfache Möglichkeiten wie
1
nohup ./meinProgramm &
oder so etwas wie
1
screen -d -m ./meinProgramm
denken. Es ist sicherlich sinnvoll, solche Möglichkeiten zu kennen, aber 
eher nichts für Produktionscode.

Und dann gibt es da ja auch noch externe Programme wie daemon(1) und 
eine Bibliotheksfunktion namens daemon(3) in der GNU-libc, die das 
leisten.

> Ich versuche das nicht in C umzusetzen, weil ich Langeweile habe oder es
> gerne unnötig verkomplizieren möchte, sondern weil ich etwas neues dazu
> lernen möchte.

Dann ist es vielleicht interessant, mehrere Varianten auszuprobieren. 
;-)

> Ich war Anfangs unsicher, ob ich mit den Dämonenprozessen überhaupt auf
> der richtigen thematischen Seite bin.

Ja, absolut.

>>1. fork()
>> [...]
>>8. openlog()
>
> Und so groß ist der Programmieraufwand bei dieser Lösung auch nicht,
> aber lerntechnisch ergibt sich einiges für Neulinge, die sich mit diesem
> Thema bislang nicht beschäftigt haben, finde ich.

Das stimmt, wirft dann aber leider wieder andere Probleme auf. Wie 
willst Du Deinen Prozeß wieder stoppen? Klassischerweise würde Dein 
Prozeß (oder das Startskript) beim Programmstart ein Pidfile anlegen 
(üblicherweise in /var/run/) und dort die Prozeß-Id hineinschreiben. Mit 
diesem Pidfile kann Dein Startskript die Prozeß-ID herausfinden und den 
Prozeß killen. Wenn Du lernen willst, wie es funktioniert, solltest Du 
den ganzen Weg gehen und ein Startskript und/oder ein systemd-Unitfile 
dafür schreiben. ;-)

Außerdem solltest Du bei klassischen Daemons die Privilegien 
beschränken. Die meisten Daemons laufen nicht unter der Kennung des 
Superusers, sondern unter ihrer eigenen Benutzerkennung. Viele Programme 
kann man dabei direkt unter ihrer Benutzerkennung starten, andere 
benötigen Superuserprivilegien um beispielsweise einen privilegierten 
Port (<1024) zu öffnen und sollten ihre Kennung danach mit setuid(3) und 
setgid(3) ändern, damit sie im Falle eines Fehlers nicht so viel 
beschädigen können.

Nun, das Coole an systemd ist, daß es sich um alles bereits selbst 
kümmert und ich als Entwickler keinen Handschlag mehr dafür machen muß. 
Insofern würde ich in Produktion heute immer auf systemd gehen. Aber 
wenn Du etwas lernen willst, ist es sicher eine gute Idee, mal so einen 
ganz klassischen UNIX-Daemon geschrieben und ein wenig damit gespielt zu 
haben. Viel Spaß!

von dd4 (Gast)


Lesenswert?

Sheeva Plug schrieb:

>Mit diesem Pidfile kann Dein Startskript die Prozeß-ID herausfinden und den 
>Prozeß killen. Wenn Du lernen willst, wie es funktioniert, solltest >Du den 
>ganzen Weg gehen und ein Startskript und/oder ein systemd- >Unitfile dafür 
>schreiben. ;-)

Der Plan sah so aus, dass ganze entweder per Hand über ein Shellscript 
oder in der ~/.config/autostart mittels etwas, dass in etwa so aussieht 
starten zu lassen.
1
[Desktop Entry]
2
Type=Application
3
Exec=programmname
4
Hidden=true
5
X-GNOME-Autostart-enabled=true
6
Name=programmname
7
Comment=log_file

>Aber wenn Du etwas lernen willst, ist es sicher eine gute Idee, mal so einen 
>ganz klassischen UNIX-Daemon geschrieben und ein wenig damit >gespielt zu haben.

Mein Reden. Ansonsten würde ich auch auf systemd setzen. Ist ja nicht 
einfach nur der Dienst des init-Prozesses, sondern hat in vielerlei 
Hinsicht neue Funktionsmöglichkeiten. Ist zumindest mein erster Eindruck 
bzw. das, was ich gehört/gelesen habe.

Aber gut, wird Zeit klein anzufangen und erstmal einen klassischen 
UNIX-Daemon zu schreiben und ein wenig damit zu experimentieren.

Danke für die Antworten!

von Sheeva P. (sheevaplug)


Lesenswert?

dd4 schrieb:
> Der Plan sah so aus, dass ganze entweder per Hand über ein Shellscript
> oder in der ~/.config/autostart mittels etwas, dass in etwa so aussieht
> starten zu lassen.
>
>
1
[Desktop Entry]
2
> Type=Application
3
> Exec=programmname
4
> Hidden=true
5
> X-GNOME-Autostart-enabled=true
6
> Name=programmname
7
> Comment=log_file
8
>

Hm... das wird natürlich nur und erst dann gestartet, wenn Du Dich in 
Deinen Desktop einloggst. Klar, kann man machen. Dann mußt Du Dir auch 
keinen Kopf mehr über Benutzerkennungen etc. machen, weil es ohnehin mit 
Deiner eigenen UID gestartet wird.

Ansonsten werden beim Login die Dateien ~/.profile und beim Starten der 
Bash die Datei ~/.bashrc abgearbeitet, auch wenn Du Dich nur auf der 
Kommandozeile ohne GUI einloggst. Das wären klassischerweise die 
Dateien, mit denen Du Deinen Daemon beim Login startest.

Wenn Dein Teufelchen automatisch beim Systemboot starten soll, kommst Du 
um ein richtiges Startskript in /etc/init.d/ oder ein systemd-Unitfile 
allerdings nicht herum.

> Mein Reden. Ansonsten würde ich auch auf systemd setzen. Ist ja nicht
> einfach nur der Dienst des init-Prozesses, sondern hat in vielerlei
> Hinsicht neue Funktionsmöglichkeiten. Ist zumindest mein erster Eindruck
> bzw. das, was ich gehört/gelesen habe.

Viele haben ja noch Vorbehalte, aber wenn Du mich fragst, ist systemd so 
ziemlich das Coolste seit geschnittenem Brot. Wenn ich hier all die 
Dinge aufzählen sollte, mit denen ich mich dank systemd in Zukunft nie 
wieder werde herumschlagen müssen, wär' ich noch bis Dienstagabend 
dran...

> Aber gut, wird Zeit klein anzufangen und erstmal einen klassischen
> UNIX-Daemon zu schreiben und ein wenig damit zu experimentieren.

Wenn Du schonmal dabei bist: es ist meistens eine gute Idee, jedes 
länger laufende Programm mal mit valgrind(1) auf Memory Leaks zu prüfen. 
Und ein Programm zur statischen Codeanalyse wie splint(1) findet viele 
"beliebte" Fehler im Code. ;-)

> Danke für die Antworten!

Immer gern!

von Daniel A. (daniel-a)


Lesenswert?

Sheeva P. schrieb:
> Ansonsten werden beim Login die Dateien ~/.profile und beim Starten der
> Bash die Datei ~/.bashrc abgearbeitet

Das hängt stark von der verwendeten shell ab, darauf würd ich mich nicht 
verlassen. Ich habe bei mir E-Mail banachrichtigungen bei logins. Für 
scripte die beim login/logout ausgeführt werden ist pam perfekt, 
insbesondere pam_exec.so

Für eigene services nutze ich mittlerweile auch systemd.

von dd4 (Gast)


Lesenswert?

Daniel Albrecht schrieb:

>Für eigene services nutze ich mittlerweile auch systemd.

Scheint beliebter zu sein, als ich angenommen habe. Wie gesagt, ich habe 
die Einführung zwar mitbekommen, auch das sie kontrovers diskutiert 
wurde, aber ansonsten ist systemd noch nie so ein Thema bei mir gewesen.

Habe gerade mal mit der Suchfunktion geschaut, ob es einen Threat zum 
Thema systemd gab oder gibt, Fehlanzeige.

Vielleicht solltet Ihr mal einen starten und Erfahrungsberichte, 
Besonderheiten oder auch nicht erfüllte Erwartungen posten, wäre 
bestimmt mal interessant.

von AAAA B. (Gast)


Lesenswert?

dd4 schrieb:
> Scheint beliebter zu sein, als ich angenommen habe. Wie gesagt, ich habe
> die Einführung zwar mitbekommen, auch das sie kontrovers diskutiert
> wurde, aber ansonsten ist systemd noch nie so ein Thema bei mir gewesen.
Das hängt von deiner Distro ab was die nutzt. Manche sind schon 
(scheinbar) voll auf systemd umgestellt andere nutzen es überhaupt 
nicht.

von dd4 (Gast)


Lesenswert?

Williy W. schrieb:

>Das hängt von deiner Distro ab was die nutzt.

Meine nutzt systemd, dass weiss ich, aber im Alltag gab es bei mir 
bislang keine Berührungspunkte, ausser systemctl, oder Anlässe sich mal 
tiefer mit der Materie beschäftigen zu müssen.

Deshalb auch die Anregung vielleicht mal einen eigenen Threat zu 
starten. Fänd ich interessant, zumal die Anwendungsbereiche oder 
Einsatzzwecke ganz schön mannigfaltig zu sein scheinen.

von Sheeva P. (sheevaplug)


Lesenswert?

Daniel A. schrieb:
> Das hängt stark von der verwendeten shell ab, darauf würd ich mich nicht
> verlassen.

Wie oft wechselst Du denn Deine Shell? Und wieviele Leute kennst Du, die 
keine Bash-kompatible Shell benutzen?

> Ich habe bei mir E-Mail banachrichtigungen bei logins. Für
> scripte die beim login/logout ausgeführt werden ist pam perfekt,
> insbesondere pam_exec.so

Puh, PAM... Als "Miterfinder" von PAM freue ich mich natürlich immer, 
wenn es einer kennt und nutzt, aber für sowas ist das eigentlich nicht 
gedacht. Immerhin ist das eine systemweite Konfiguration, auf 
Multiusersystemen und wenn man untrusted User hat geht das also nicht 
bzw. nur schwer.

Nee, da halte ich es für sinnvoller, die Startupskripte der jeweiligen 
Shell zu benutzen. Ob die jetzt .bashrc oder .csrc heißen, weiß der 
Benutzer einer Exotenshell ja sicher selbst.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.