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

Hi monks,

I would appreciate your advice on using the unix batch (at) command to run a cgi at a specified time. I have been looking at system() and backtick methods.

e.g. from unix prompt (this works):

[unix]$ at now + 2 minute <<EOF ? /......./mifuture.cgi idnumber=222 ? EOF warning: commands will be executed using /bin/sh job 76 at 2001-01-24 14:22
I have tried the following perl offline:
#!/usr/bin/perl `intranet/develop/Susp/mifuture.cgi idnumber=218`; `at now + 2 minute <<EOF`; `/....../mifuture.cgi idnumber=220`; `EOF` ; $atq = `atq`; print qq( ATQ: $atq<BR>);

When run offline this passes the idnumber, but mailings for idnumber 218 and 220 are sent at same time. mifuture.cgi sends mail including idnumber. When run online (from browser) the cgi with appropriate form doesn't pass the idnumber.

Thanks in advance for any contributions,
regards,
Roy

2001-03-04 Edit by Corion : Added <CODE> tags

Replies are listed 'Best First'.
Re: Unix batch from perl?
by Fastolfe (Vicar) on Jan 24, 2001 at 20:57 UTC
    'at' will accept its command in the form of a script sent over STDIN:
    open(AT, "|at now + 2 minutes") or die "..."; print AT "/....../mifuture.cgi idnumber=220\n"; close(AT) or die "..."; # non-zero exit status
    This seems like a very unusual thing to do. CGI scripts are meant to be running under a web server. Why are you scheduling it? Perhaps you want to re-write this as a true scheduled script and set up a cron job for it?

    A better solution might be to queue up your requests and send them at intervals, assuming it's the instant batch you're trying to avoid:

    fork && exit; # CGI script returns/exits right then # This continues processing in the background while ($_ = shift(@things_to_do)) { sleep $seconds; process($_); }
    I'm curious why you are trying to avoid sending out two mailings at once...? I can't imagine a case where the mail server might have problems with it.
Re: Unix batch from perl?
by adamsj (Hermit) on Jan 24, 2001 at 20:56 UTC
    When you say:
    #!/usr/bin/perl `intranet/develop/Susp/mifuture.cgi idnumber=218`; `at now + 2 minute <<EOF`; `/....../mifuture.cgi idnumber=220`; `EOF` ; $atq = `atq`; print qq( ATQ: $atq);
    each backticked line runs in sequence. Try this:

    (NOTE: Untested but close, and right in principle.)

    #!/usr/bin/perl `intranet/develop/Susp/mifuture.cgi idnumber=218`; `at now + 2 minute <<EOF /....../mifuture.cgi idnumber=220 EOF` ; $atq = `atq`; print qq( ATQ: $atq);
    or something like it. And read up on backticks and system().

    UPDATE: My solution will work (I think), and you can learn from studying it, but in all honesty, I think this answer from Fastolfe is better--I'd somehow overlooked piping.