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

Hiya Monks,

I've been having an excruciating time scheduling the deletion of a session file in a CGI script. It seems like it would be simple enough to make a system call:

system "rm $session_file | at now + 1 minute";
But what happens there is the rm command executes right away and I lose my session file immediately, and the schedule has nothing in it, apparently. I try:
system "at now + 1 minute < rm $sesson_file";
I get a "garbled time" complaint in my Apache logs. I've tried all kinds of crazy indirection, like:
my $command = "rm $session_file; system "echo $command | at now + 1 minute";
and a couple dozen permutations to no avail. I think I'm not grasping something about how perl is executing this stuff. What am I not understanding correctly? Any input would be appreciated.

Replies are listed 'Best First'.
Re: executing "at" from perl
by moritz (Cardinal) on Nov 16, 2009 at 09:34 UTC
    echo rm $session_file | at now + 1 minute

    should work. This has nothing to do with how perl executes it, but everything with how the shell does it - if you type the contents of the system call in the shell you get the same behaviour.

    You could also open a pipe, and write to it:

    open my $at, '|-', 'at', qw(now + 1 minute) or die "can't open pipe to 'at': $!"; print $at "rm $session_file"; close $at or die $!;

    Or you could use CGI::Session which handles session timeouts for you in a transparent way.

    Perl 6 - links to (nearly) everything that is Perl 6.
      By the way, it turned out the problem here was that the Apache user didn't have a shell. Put a shell in for him, and it worked great.

      That's not too cool, of course, so I'm still hunting other ways--possibly execution environment-related.

Re: executing "at" from perl
by gmargo (Hermit) on Nov 16, 2009 at 13:04 UTC

    I cringe when I see rm being used with some unknown parameter, seemingly derived from a web page.

    For the love of your computer system, please run a shell or perl script instead, which does some amount of checking before a remove. It's only a matter of time before that rm comes back to bite you where the sun never shines. Imagine $session_file set to "-rf /" or "*" somehow. Sure, it can "never happen". Just wait.

Re: executing "at" from perl
by cdarke (Prior) on Nov 16, 2009 at 12:46 UTC
    at(1) reads its command from standard input, so a pipe should work, but from the command as text, don't run the command as in your first example.

    Check that the web server is allowed to run at(1), there is an at.deny and an at.allow file which might be blocking you (usually in /etc).
    I suggest you try the at(1) command from the UNIX shell first, but make sure you are signed on as the same username that is executing your script.
Re: executing "at" from perl
by Fox (Pilgrim) on Nov 16, 2009 at 13:15 UTC
    the first 2 are only passing the output of rm to at, what you really want to do is pass the command string so the 3rd should work if the missing quote is just a typo in the post.
      Thanks, all.

      My option number 3 does not work:

      system "echo rm $session_file | at now + 1 minute";
      The session file is created, the job shows up in atq, but it fails silently. It's the 'silently' part that is most maddening. Hm maybe I should direct errors somewhere..but the apache user isn't in /etc/at.deny, and indeed I forced a shell on the user and it worked okay--I thought cdarke might be on to something :-)

      gmargo: I hear you loud and clear. I think I'm going to check out moritz suggestion and check out CGI::Session. However, in this case I'm putting in the 'at' right after creating the session file, so at least it isn't from user input. So I *presume* it's okay, but yeah, I'll check out CGI::Session :-). I hear ya loud and clear, and appreciate the input.

      Really now it just bugs me that I don't know why it fails.

        Hm actually it doesn't look like CGI::Session automatically cleans up old session files? I was wondering how that would work.

        This script is going to run on a server I don't admin, so I'm concerned about leaving these things lying around on his hard drive.