Pass output from shell script back to perl

S

sitnam81

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!
 
A

A. Sinan Unur

[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
 
G

Gunnar Hjalmarsson

sitnam81 said:
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.

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.
 
T

Tad McClellan

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.
 
S

sitnam81

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.
 
T

Tad McClellan

sitnam81 said:
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?
 
S

sitnam81

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.
 
T

Tad McClellan

[ Please quote some context in followups like everyone else does. ]


sitnam81 said:
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!
 
A

A. Sinan Unur

Please quote some context.
I would like the output from the shell script to be fed back into the
perl script.

Then why are you using system?

Do you know what system returns?

Have you read

perldoc -f system

Sinan
 
G

Gunnar Hjalmarsson

Tad said:
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?
 
S

sitnam81

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 :)
 
T

Tad McClellan

Gunnar Hjalmarsson said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top