Pass output from shell script back to perl

Discussion in 'Perl Misc' started by sitnam81, Apr 28, 2005.

  1. sitnam81

    sitnam81 Guest

    Hello all,

    I am working on a web front end that would allow administrators to
    manage Solaris users on multiple servers -- a php page with a form
    passes input to this perl cgi script, which ssh's to the selected
    servers and executes shell scripts to add/remove the input user. These
    schell scripts return one line of output, which I want to pass back to
    the perl script, to display the results. I keep getting "500" errors
    with the following in the apache log:

    [error] malformed header from script. Bad header=user inputusername
    removed: add_remove_user.cgi, referer: http://IP/useradmin.php

    Like the example above the output from the shell script is like "user
    inputusername removed" -- how can I pass this back to the page? Here
    is the perl scipt:

    *******************************************************************
    #!/usr/bin/perl -w

    print "Content-type:text/html\n\n";

    $loop = 0;
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    @pairs = split(/&/, $buffer);
    foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    if($value eq "ON") {
    $SERVER{$loop} = $name;
    $loop++
    }
    else {
    $FORM{$name} = $value;
    }
    }

    $loopc = $loop;
    $user = "specifieduser";
    $addcommand = "sudo /etc/scripts/useradd $FORM{uname} $FORM{UID}
    $FORM{group}";
    $rmcommand = "sudo /etc/scripts/userremove $FORM{uname}";

    print "<html><head><title>Form Output</title></head><body>";
    print "<h2>Results from FORM post</h2>\n";

    if($FORM{pass} eq "") {
    print "Please enter a password<br>";
    print "<br><a href='javascript: history.go(-1)'>Back</a>";
    }

    elsif($FORM{pass} eq $FORM{pass2}) {
    if($FORM{radio} eq "add") {
    for($loop = 0; $loop < $loopc; $loop++)
    {
    print "ADDING Username: $FORM{uname} UID: $FORM{UID} Group:
    $FORM{group} to $SERVER{$loop}\n\n";
    #$ADDRESPONSE = system("ssh", "-l", "$user", "-q", "$SERVER{$loop}",
    $addcommand);
    #print "$ADDRESPONSE\n";
    print system("ssh", "-l", "$user", "-q",
    "$SERVER{$loop}", $addcommand);
    }
    }
    else {
    for($loop = 0; $loop < $loopc; $loop++)
    {
    print "REMOVING Username: $FORM{uname} UID: $FORM{UID}
    Group: $FORM{group} to $SERVER{$loop}\n\n";
    #system("ssh", "-l", $user, "-q", $SERVER{$loop},
    $rmcommand, "| 2>&1 >/dev/null");
    $RMRESPONSE = system("ssh", "-l", "$user", "-q",
    "$SERVER{$loop}", $rmcommand);
    print "$RMRESPONSE\n";
    print system("ssh", "-l", "$user", "-q",
    "$SERVER{$loop}", $rmcommand);
    }
    }

    print "<br><a href='javascript: history.go(-1)'>Back</a>";
    }

    else {
    print "Passwords do not match<br>";
    print "<br><a href='javascript: history.go(-1)'>Back</a>";
    }

    print "</body></html>";

    *******************************************************************

    Thanks!
    sitnam81, Apr 28, 2005
    #1
    1. Advertising

  2. "sitnam81" <> wrote in
    news::

    > [error] malformed header from script. Bad header=user inputusername
    > removed: add_remove_user.cgi, referer: http://IP/useradmin.php


    Well, you are not sending the correct headers to the browser.

    > *******************************************************************
    > #!/usr/bin/perl -w


    use warnings;

    is better because it allows you to selectively turn warnings on and off.

    You also need:

    use strict;

    > print "Content-type:text/html\n\n";


    Are you sure that is correct?

    > $loop = 0;
    > read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    > @pairs = split(/&/, $buffer);
    > foreach $pair (@pairs) {
    > ($name, $value) = split(/=/, $pair);
    > $value =~ tr/+/ /;
    > $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;


    Please do not use buggy home-brewed solutions for parsing CGI data.

    use CGI;

    perldoc CGI

    should get you started.

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Apr 28, 2005
    #2
    1. Advertising

  3. sitnam81 wrote:
    > I am working on a web front end that would allow administrators to
    > manage Solaris users on multiple servers -- a php page with a form
    > passes input to this perl cgi script, which ssh's to the selected
    > servers and executes shell scripts to add/remove the input user. These
    > schell scripts return one line of output, which I want to pass back to
    > the perl script, to display the results. I keep getting "500" errors
    > with the following in the apache log:
    >
    > [error] malformed header from script. Bad header=user inputusername
    > removed: add_remove_user.cgi, referer: http://IP/useradmin.php


    I don't know why you get that error. You shouldn't, since you have:

    > print "Content-type:text/html\n\n";


    at the beginning of the script as well as several other print statements
    before any system() command is executed.

    <snip>

    > print system("ssh", "-l", "$user", "-q", "$SERVER{$loop}", $addcommand);


    Nevertheless, you'd better study

    perldoc -f system

    and read about what you should use instead to capture the output.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Apr 28, 2005
    #3
  4. sitnam81 <> wrote:


    > I keep getting "500" errors



    So you have already seen the answer to your Frequently Asked Question then?

    perldoc -q 500

    My CGI script runs from the command line but not the browser. (500
    Server Error)


    > read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    > @pairs = split(/&/, $buffer);
    > foreach $pair (@pairs) {
    > ($name, $value) = split(/=/, $pair);
    > $value =~ tr/+/ /;
    > $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    >
    > if($value eq "ON") {
    > $SERVER{$loop} = $name;
    > $loop++
    > }
    > else {
    > $FORM{$name} = $value;
    > }
    > }



    If you insist on decoding forms yourself, then you are on your own.

    perldoc -q form

    How do I decode a CGI form?



    > print system("ssh", "-l", "$user", "-q",



    If you read the documentation for the function that you are
    using you will see both what system() returns (which you
    are then print()ing) and how to capture the output from
    external programs.

    This is not a "read the docs to me" service.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Apr 28, 2005
    #4
  5. sitnam81

    sitnam81 Guest

    Well I am able to test all components successfully:
    1.) The ssh + shell script component successfully returns the desired
    result
    2.) The perl works fine -- loads in the form data and correctly calls
    the desired script
    3.) If I remove the output of the script, the page returns fine after
    submitting

    Only when I allow the script to return results does it cause the 500
    error. This leads me to believe that it is not a webserver problem
    because it can handle the perl and the originating php page. Therefore
    I believe it is a problem with the way the perl script handles the
    output from the shell script.
    sitnam81, Apr 29, 2005
    #5
  6. sitnam81 <> wrote:

    > I believe it is a problem with the way the perl script handles the
    > output from the shell script.



    They way you are calling the shell script, it is not a problem with
    Perl.

    The output goes to wherever the output normally goes, often STDOUT
    (which would be inherited from the perl process).

    Where do you _want_ the STDOUT from the shell script to go?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Apr 29, 2005
    #6
  7. sitnam81

    sitnam81 Guest

    I would like the output from the shell script to be fed back into the
    perl script.
    Then i would like it to include that output in the resulting html for
    the "submit" page.
    sitnam81, Apr 29, 2005
    #7
  8. [ Please quote some context in followups like everyone else does. ]


    sitnam81 <> wrote:

    > I would like the output from the shell script to be fed back into the
    > perl script.



    Then I have already answered your question in an earlier followup.

    Did you follow the advice I gave? It contains the answer to your question!


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Apr 29, 2005
    #8
  9. "sitnam81" <> wrote in
    news::

    Please quote some context.

    > I would like the output from the shell script to be fed back into the
    > perl script.


    >>> print system("ssh", "-l", "$user", "-q", "$SERVER{$loop}",
    >>> $addcommand);


    Then why are you using system?

    Do you know what system returns?

    Have you read

    perldoc -f system

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Apr 29, 2005
    #9
  10. Tad McClellan wrote:
    > sitnam81 wrote:
    >> I would like the output from the shell script to be fed back into the
    >> perl script.

    >
    > Then I have already answered your question in an earlier followup.


    Are you sure of that? If you are, I'm curious. How can the server
    generate the error mentioned in the original post when there are several
    valid print statements before the system() call, including a
    content-type header?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Apr 29, 2005
    #10
  11. sitnam81

    sitnam81 Guest

    Finally got this working...
    This is what I needed to do:

    $RMRESPONSE = qx(ssh -l $user -q $SERVER{$loop} $rmcommand);
    print "<br>$RMRESPONSE<br>";

    Thanks to everyone for your help, I'm a newbie to perl :)
    sitnam81, Apr 29, 2005
    #11
  12. Gunnar Hjalmarsson <> wrote:
    > Tad McClellan wrote:
    >> sitnam81 wrote:
    >>> I would like the output from the shell script to be fed back into the
    >>> perl script.

    >>
    >> Then I have already answered your question in an earlier followup.

    >
    > Are you sure of that?



    Yes, I had previously answered the question in the Subject.


    > If you are, I'm curious. How can the server
    > generate the error mentioned in the original post when there are several
    > valid print statements before the system() call, including a
    > content-type header?



    I couldn't reconcile that either, so I could not address that part.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Apr 29, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christian Heimes
    Replies:
    0
    Views:
    589
    Christian Heimes
    Feb 27, 2008
  2. Gerardo Herzig
    Replies:
    1
    Views:
    1,061
    Philipp Pagel
    Feb 27, 2008
  3. D'Arcy J.M. Cain
    Replies:
    0
    Views:
    850
    D'Arcy J.M. Cain
    Feb 27, 2008
  4. PhEaSaNt PLuCKeR

    perl script to pass data to another perl script?

    PhEaSaNt PLuCKeR, Oct 30, 2005, in forum: Perl Misc
    Replies:
    1
    Views:
    145
  5. moongeegee

    execute a shell script in a shell script

    moongeegee, Dec 3, 2007, in forum: Perl Misc
    Replies:
    2
    Views:
    240
    Ben Morrow
    Dec 4, 2007
Loading...

Share This Page