Issue
I have a Perl script that needs to act in a particular way if it was invoked by the firstboot script or invoked by a process that firstboot spawned. I have this routine handleFirstBoot
and it seems to work ok, but there is probably better way to write this routine. So please take a look ...
sub handleFirstBoot {
my $child_id = shift || $$;
my $parent_id;
foreach (`ps -ef`) {
my ($uid,$pid,$ppid) = split;
next unless ($pid eq $child_id);
$parent_id = $ppid;
last;
}
if ( $parent_id == 0 ) {
debug "firstboot is NOT an ancestor.\n";
return;
}
my $psout = `ps -p $parent_id | tail -1 |sed -e's/^ //g'| sed -e's/ */ /g'|cut -d' ' -f4`;
if ( $psout =~ /firstboot/ ) {
debug "firstboot IS an ancestor. Set post option.\n";
$opt{'post'} = 1;
return;
} else {
# recursive case
handleFirstBoot($parent_id);
}
}
Solution
Can I offer an alternative approach - from the comments, the problem you are trying to solve is a startup script stalling because it's waiting for this one to return.
So can I suggest that fork()
is probably your friend here?
my $pid = fork();
if ( $pid ) {
exit;
}
sleep $delay_time;
do_stuff();
What will happen is - your script will be called, and the caller will return immediately, but a parallel instance will spawn and delay the random delay interval - and for bonus points, this will work the same in cron
too.
But as you seem to note in the comments - the 'good' solution is not to do it that way at all - I would suggest that looking at say, anacron
which is available on most Linux systems would be exactly the tool for this particular job.
Answered By - Sobrique Answer Checked By - Candace Johnson (WPSolving Volunteer)