title image


Smiley Re: Perl in Hintergrund schicken
Das ist relativ einfach mittels des Unix Syscalls fork() möglich.



Obwohl seit Perl 5.6.0 fork() auch auf Win32 funktionieren soll, ist es sicherer dies auf einem Unix zu implementieren.

(Jemand, der sich mit Perl unter Win32 auskennt, möge Dir darüber Auskunft geben, wie das dort geht)



Unter Unix jedenfalls ist das ein Standard Verfahren.

Das ganze läuft auch unter dem Stichwort daemonization.



Vielleicht kurz die Schritte:





Prozess (also Dein Skript) macht eine Kopie von sich selbst mittels fork()

Der klonende Elternprozess verabschiedet sich via exit()

$$ bekommt jetzt die PID der Kopie (also des Child Procs) und muß neuer Session Leader einer Prozess Gruppe werden.

Dazu verwendet man den POSIX Syscall setsid().

(dies ist Voraussetzung dafür, daß ein Schließen der Shell, von der Dein Skript gestartet wurde durch das SIGHUP, das dabei allen Kinder geschickt wird nicht zum Beenden Deines Skripts führt).

Damit der neue Session Leader aus dem Hintergrund nicht (versehentlich noch die File Descriptoren STDIN, STDOUT, STDERR liest bzw. schreibt (z.B. durch die Fehlermeldungen eines eigenen neuen Child Procs), werden diese von bzw. auf /dev/null umgeleitet.

Der Hintergrund Prozess sollte dann nach '/' wechseln, damit umount() Versuche nicht blockiert werden.

Evtl. ist sogar ein chroot() angebracht (wenn Clients bedient werden, die nicht vertrauenswürdig sind)

Schließlich sollten noch geerbte nicht benötigte Umgebungsvariablen gelöscht bzw. weitere File Descriptoren geschlossen werden.

Ggf. kann jetzt noch die EUID gewechselt werden (falls der Prozess z.B. mit root Rechten gestartet wurde.



Sehr grob könnte das etwa so aussehen:







use POSIX 'setsid'; # zum Import von setsid()



$child_pid = fork;

die "cannot fork: $!\n" unless defined $child_pid;



exit if $child_pid; # hier beendet sich der Parent Proc



setsid(); # wir werden Session Leader und trennen uns vom Terminal



open STDIN, '
open STDOUT, '>/dev/null';

open STDERR, '>&STDOUT';



umask 0; # Rücksetzen einer geerbten umask



chdir '/'; # ggf. Mount Point frei machen



delete @ENV{qw(ENV IFS CDPATH)}; # Säubern der geerbten Umgebung

$ENV{PATH} = '/bin:/usr/bin:/usr/sbin:/usr/local/bin';







Eine sehr schöne Einführung zur IPC unter Perl findest Du über

perldoc perlipc





geschrieben von

Login

E-Mail:
  

Passwort:
  

Beitrag anfügen

Symbol:
 
 
 
 
 
 
 
 
 
 
 
 
 

Überschrift: