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)?
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".
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.
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?
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.
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? :-/
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.
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.
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. ;-)
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.
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ß!
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!
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!
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.
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.
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.
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.
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.