#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2004
    Posts
    3
    Rep Power
    0

    Running a shell script from a perl cgi


    I am having real trouble with a tiny little webpage I am trying to make!

    I want my web form to call a script that returns a simple message to the browser and kicks off a shell script that loops through a massive list of email addresses and sends an email to them. I want this to execute in the background because it will take ages to run through and I want to give the user some feedback straight away.

    I chose to use a perl script using mod:CGI as the first step in the process because of its parameter handling capabilities (it needs to take in a massive list of addresses among other things) and its abilty to return html.

    This perl script should then return some html AND THEN KICK OFF A SHELL SCRIPT to run the mailer loop. I have tried using both exec and system to do this. If i use exec the perl script does not return the html message to the browser, and if I use system it would wait until the shell script completes (a long time) which are both undesirable. Is there another way to do this that meets my needs?

    ANYWAY, no matter what I try, the perl script REFUSES to kick off the shell script when run from the webpage. I have run it at the command line in offline mode passing in some variable manually, and it works fine. Both of the scripts (the perl and the shell) have fully open permissions.

    I have heard a vague rumour from one of my workmates that perl cgi scripts cannot run shell scripts. Is this true? It seems like it might be, as I have replaced the "exec [myscript]" line with "exec 'mailx [some stuff]'" and the mailx command executes fine, just not my shell script.

    Any suggestions? I have been trying to fix this damn problem for days now and its incredibly frustrating.
  2. #2
  3. 11
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Jul 2001
    Location
    Lynn, MA
    Posts
    4,635
    Rep Power
    83
    Your workmate is wrong. Perl can run any kind of executable it can reach on your server. That's one of the reasons it's called the "duct tape of the internet," along with www.cpan.org

    Some scripts are best launched by cron and not by CGI interaction. Long-running mail scripts are one of them.

    My suggestion would be to have your CGI interface take in the addresses and the message. Then have a task in the background that picks up the addresses and sends them out on a schedule. Create a queue. Once a message has been sent, delete the addresses and the message from your queue.

    I'd use MIME::Lite as your mailing module- it's very flexible and can send pretty much any kind of email you want over SMTP or by default via sendmail pipes locally.
    Last edited by Hero Zzyzzx; March 24th, 2004 at 09:13 PM.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2004
    Posts
    3
    Rep Power
    0
    Thanks for your reply.

    I didn't think my workmate could be right, it made no sense to me, but the fact that the shell script wasnt being exec'd and other commands were seems to suggest it might be true. Good to know its not.

    This particular application is not suitable for cron as it will be a seldom used page to send out newletters at random times, probably around once a month on average. The person doing the sending will not be a technical person either, it will usually be some kind of secretary. The webpage with cgi seems like a good option as it allows this to be done on demand only.

    My mailer is actually a java prog that sends the mail from our outside mailhub, rather than the machine it is being run on. This is because we are trying to avoid overloading the internal email system. This java prog is run in a loop in the shell script. I'll start looking into MIME::Lite to see if this can satisfy my needs, but at present I still want to know why I am having this problem.

    BASICALLY all I want to know is why this perl script works fine when run from the command line in "offline" mode, but doesnt manage to run the shell script when executed from the webpage.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Location
    Philippines
    Posts
    6
    Rep Power
    0

    Lightbulb


    hmmm.. I think when you issue the mail command on your shell it expect some body or some STDIN to be executed.

    I usually do this task with system and I use an anubis or sendEmail mailer e.g.:

    system `/usr/local/bin/sendEmail -f from_email\@domain.net -t to_email\@domain.net -u "[SUBJECT]" -m "[Message body]" -s outgoing_mail_server_ip -a /dir/attachment_file.txt`

    HTH,
    ~gams
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2004
    Posts
    3
    Rep Power
    0
    Thanks, but not in this case. I am not using anything that requires stdin, my java mailer does all that itself.

    I did mention mailx, and that does require stdin to complete the body, but I was cat 'ing a file into it which meant it wasnt taking stdin, and this wasnt the problem. And i was only mentioning it as an example of something that did work.

    This wouldnt explain why the script works from the cmd line but not the webpage.
  10. #6
  11. kill 9, $$;
    Devshed Supreme Being (6500+ posts)

    Join Date
    Sep 2001
    Location
    Shanghai, An tSín
    Posts
    6,897
    Rep Power
    3887
    Originally Posted by gamieboy
    system `/usr/local/bin/sendEmail -f from_email\@domain.net -t to_email\@domain.net -u "[SUBJECT]" -m "[Message body]" -s outgoing_mail_server_ip -a /dir/attachment_file.txt`
    I couldn't let this one passed uncommented upon.

    I'd nearly bet my house that you're not doing what you want to do there. You're making two system calls - one with the backticks and then you're trying to execute its output with system. Here's a simple example:
    Code:
    system `echo 'ls -l'`;
    The backticks run the 'echo' command, which returns the string 'ls -l'. system() then runs that. One or the other should be enough.

    As for your problem MrRogers, you can launch a background process as you would in the shell, by putting a & after it:
    Code:
    system('mailer --options --etc &');
    Downside of this is that your Perl script will have no way of knowing whether the mails were sent successfully. Perhaps you could output your mail program's output to a file that you can check later.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2004
    Posts
    1
    Rep Power
    0

    Question Running Shell Script from CGI script


    Hi everyone,
    I have a problem similar to MrRogers, but not exactly. I'm doing a one-time update to a CGI script. I did a little CGI programming years ago and I don't remember much about it. All I need to do is run a Korn shell script at a certain point in my CGI page, but I don't know the syntax. Here's the code from my CGI page:

    if {[info exists error]} {
    errormsg "$error <BR><A HREF=\"password.pl?id=$env(QUERY_STRING)\">Ple\
    ase try again</A>"
    } else {
    #CALL MOVEPASSWD SCRIPT HERE
    successmsg "Your password has been changed.<BR> To verify your new pas\
    sword works, <BR><A HREF=\"logout_check.pl?id=$env(QUERY_STRING)\">Login A\
    gain</A>"
    }
    exit

    On the line that says "#CALL MOVEPASSWD SCRIPT HERE" I want to execute a file called movepasswd (no extension on this file). There are no arguments for it. My CGI script is in the folder location inet2/apache/cgi-bin and the movepasswd script is in the folder location inet2/tools. Can anyone tell me what syntax I need to use to call the movepasswd script? Any help would be much appreciated!

IMN logo majestic logo threadwatch logo seochat tools logo