> -----Original Message----- > From: Paul D. Kraus [mailto:[EMAIL PROTECTED] > Sent: Monday, May 09, 2005 9:19 AM > To: Perl Beginners List > Subject: Fork - Process ID > > > Sceniro. > I have many cron jobs that run perl scripts. These perl > scripts launch TbredBasic Applications. The problem I keep > finding these processes hung but I have noway of finding out > which program is actually causing the problem. When the > tbredbasic application launches the processes name is always BASIC. > > I wanted to write a program that would write out the process > id and the perl program that spawned it to a file then > destroy that file when the program fails. This way I can just > look at the "log" and see that program X is what keeps hanging. > > So I have been experminting with the fork command but I am > confused as to the out put I get. Below is the code and its > output follows. First please explain why the pid prints twice > and second let me know if there is a better way to achive > what I am trying to do. > > TIA > Paul >
Hi Paul. Fork is fun to play with! I've put some comments below: > #!/bin/perl > > use strict; > use warnings; > > defined( my $pid = fork ) or die "Cannot fork: $!"; # right here, there are two processes running. The first one, and the one that got forked. # both processes have the $pid variable. The original process should receive the new processes # PID as the return value from fork, so it's $pid = 1111 (or, whatever the system returns). # The new process will receive a 0 (zero) from fork. Now you can use that $pid value to split # your code down two different paths. > print "pid:$pid\n" # When I ran your code, the following was printed: # pid: 1275 # pid: 0 # Your output was not included in the email. Was your output different than this? > unless( $pid ) { > exec "date"; > die "cannot exec date: $!"; > } # This unless block should run date command if the process is the NEW process. The old process # with a 0 (zero) value for $pid, will skip the 'exec' and 'die' lines of code. Is that what you intended? Here is a subroutine template I use in my daemon scripts, if it helps. The 'setsid' function requires that you import the POSIX module somewhere in your code: use POSIX 'setsid'; sub daemonize { # A forked process usually doesn't want to be in some random directory, so we change to root (/) chdir '/' or die "Can't chdir to /: $!"; # The forked process doesn't want to read from standard-in, nor do we want it to spam the # standard-out with random messages. open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '/dev/null' or die "Can't write to /dev/null: $!"; # Here is where the actual fork takes place defined( my $pid = fork ) or die "Can't fork the daemon: $!"; # Here the script that starts the forked process will end exit if $pid; # original (terminal) process dies here # This will give the forked process it's own session and make the process it's own session leader setsid or die "Can't start a new session: $!"; # finally, we'll duplicate standard-error to wherever standard-out is, again to prevent spamming standard-out open STDERR, '>&STDOUT' or die "Can't dup STDOUT: $!"; } Hope this helps you some. --Errin -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>