Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a bit of code for a cron script. Its pretty obvious what its doing.

What I can't figure out is, why it won't die. I've even used die "blah"; after the last else conditional. I've put exit; everywhere I can think of. I've even defined subroutines for each function after the if does its magik.

Any ideas about what I could do to make this thing die?

I'm sure once cron finishes its work, it would kill the remaining process, but I just want to make sure it exits cleanly.

#!/usr/bin/perl -wT use strict; $ENV{PATH} = '/bin:/usr/bin:/usr/bin/X11:/usr/local/bin:/usr/bin:/usr/X11R6/bin'; my $ircd = `ps -u me | grep ircd`; my $services = `ps -u me | grep wrecked`; if ($ircd) { print "Ircd is up!\n"; } else { print "Starting Ircd......\n"; `sudo -u dsirc /home/me/Unreal3.1.4/src/ircd`; } if ($services) { print "Services are up!\n"; } else { print "Starting Services......\n"; `sudo -u dsirc /home/me/services/wrecked`; }

Replies are listed 'Best First'.
Re: Why won't it die??
by Aristotle (Chancellor) on Aug 22, 2002 at 02:30 UTC
    I can't actually help with your real question, I'm afraid. I want to toss in some pointers though. See comments.
    #!/usr/bin/perl -wT use strict; $ENV{PATH} = '/bin:/usr/bin:/usr/bin/X11:/usr/local/bin:/usr/bin:/usr/X11R6/bin'; my @process = `ps -u me`; # only call ps(1) once if (grep /ircd/, @process) { # use Perl's builtin grep print "Ircd is up!\n"; } else { print "Starting Ircd......\n"; # use system(LIST) rather than backticks system qw(sudo -u dsirc /home/me/Unreal3.1.4/src/ircd) or die "Failed to launch ircd!\n"; } if (grep /wrecked/, @process) { print "Services are up!\n"; } else { print "Starting Services......\n"; system qw(sudo -u dsirc /home/me/services/wrecked) or die "Failed to launch services!\n"; }
    Update: added checks for system success.

    Makeshifts last the longest.

      Thanks for the pointers Aristotle! I see all your points.

      Safer to make system calls with the built in function, rather than the backtic?

      And storing both ps calls into one aray is less code, so its slightly faster(and prettier to boot)??

        Using system is a question of economy here. With the backticks, you capture the command's output - only to throw it away. The system(LIST) form also avoids invoking the shell. Actually, if you were interpolating user input into the call, avoiding the shell via system(LIST) increases security as well, because you don't have to worry about shell metacharacters, but that's not the case here.

        The benefit of storing the output from ps is twofold. First of all, you only need to call the program once, as opposed to twice. And then you can use Perl's own grep to search that data - as opposed to spawning a process for the grep binary, twice. What grep really returns is a list of all the list that matched, but we're not storing it. Using a list in an if condition simply checks if the list is empty or not, and that's what we do here.

        Btw, have another look at the post. The first time around, I forgot another detail: I wasn't checking for whether the system calls succeed. Stupid omission now fixed..

        Makeshifts last the longest.

Re: Why won't it die??
by Bobcat (Scribe) on Aug 22, 2002 at 03:05 UTC
    Do /home/me/Unreal3.1.4/ircd and /home/me/services/wrecked auto-daemonize themselves? In other words, do they automatically go to the background if you type the commands in manually, or do you have to do a CTRL-Z and then bg to background them?

    You might try adding an ampersand (&) after the command to see if that fixes it.

      Yes, both these use background processes, the binaries put them back there automagically.

      Good thinking anyways!

        Is this a root cron or a user cron?

        sudo on my machine give me some funky errors and such if I run it when I'm root. Perhaps a su - username instead of the sudo would work?

        If it's a user cron, do you have to authenticate your sudo session with a password? If so, the cron-spawned shell is probably sitting there waiting for password input on STDIN. It'll eventually time out, but since the STDIN stream doesn't belong to a TTY that can give you input, it'll sit there.

        Hope this helps!

Re: Why won't it die??
by graff (Chancellor) on Aug 22, 2002 at 03:15 UTC
    If you run ircd and wrecked at the command-line prompt (as user "dsirc"), do they do something and then exit right away, or do they keep running until you kill or suspend them?

    If they keep running, use a system call with a single quoted string for the whole command line (not back ticks), and include an ampersand "&" as the last token on the command string, so as to run the process in the background.

      To answer your question, ircd spits out some confirmation info, then exits, and wrecked just exits after you run the command.

      Now, odly enough, rewriting the code simmilar to how Aristotle has it above actually corrected the problem! Must have been some corruption of some kind with the using the backtics, thats all I can figure. The once again proves that a function was coded in for a reason, so use it!!

      Thanks Guys!