Getting a Perl file to run under Ubuntu?

Actually I take that back, your perl script is bad, can you copy and paste that script here? You have some sort of error in it.

There’s the error log, back in a min with the Perl script…

As you can see, I tried my echo.pl file a couple of times too. That one looks to be failing on permissions, which doesn’t surprise me based on the note I made above somewhere.

Yeah, so your perltest.pl one is due to bad script. You either have output or something happening before headers are written.

The echo.pl is a permission issue, meaning it didn’t have chomd a+x run against it.

Apologies for the lack of editable version - can you cut & paste in nano?

Yeeah, that’s a bad script. I made the same mistake at first (it has been many years since I’ve written a Perl script). Remove the ###Start### and ###End### lines. Make sure the file starts with that she-bang statement #!

1 Like

I took the thing too literal huh?

I did too at first and then after looking at what I did, I face palmed as I knew better.

Ah, I forgot all about those being there.

I didn’t include the “Start” or “End” in the script and had the shebang as the first line out of habit.

That’s a wrap folks…

Time to fix the permissions on echo.pl now, then maybe, just maybe, I can carry on with learning JS, which is where this all started.

2 Likes

Almost…

I’ve got the file permissions and the ownership on echo.pl sorted out, but it’s still coming up with the same issue as perltest.pl did. This time though, the error log is saying that echo.pl “End of script output before headers”.

This time the script ‘ought’ to be correct as supplied, as I didn’t write it - this is it though.

#!C:/Perl/bin/perl                                

# This is a Perl script written by Mike McGrath to display, 
# in alphanumeric name order, 
# all name/value pairs submitted from a HTML form.
# It requires Perl to be installed and this script 
# should be placed on the web server, 
# in the directory configured for CGI scripts.

# Process request ----------------------------------------------------------------------

  if ($ENV{'REQUEST_METHOD'} eq 'GET') 
  {                                                  
    @pairs = split(/&/, $ENV{'QUERY_STRING'});              
  }                                                   
  elsif ($ENV{'REQUEST_METHOD'} eq 'POST') 
  {                                                    
    read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});                             
    @pairs = split(/&/, $buffer);                          
    if ($ENV{'QUERY_STRING'}) 
    {                            
      @getpairs =split(/&/, $ENV{'QUERY_STRING'}); 
      push(@pairs,@getpairs);   
    }                                                       
  }                                                    
  else 
  {                                               
    print "Content-type:text/html\n\n";                 
    print "Unrecognized Request Method - Use GET or POST.";
  }                                                                                                     

  foreach $pair (@pairs) 
  {                                                  
    ($key, $value) = split(/=/, $pair);                  
    $key =~ tr/+/ /;                                     
    $key =~ s/%(..)/pack("c", hex($1))/eg;             
    $value =~ tr/+/ /;                                   
    $value =~ s/%(..)/pack("c", hex($1))/eg;           
    $value =~s/<!--(.|\n)*-->//g;  # ignore SSI
    if ($formdata{$key}) 
    {                                         
      $formdata{$key} .= ", $value";                          
    }                                                    
    else 
    { 
    $formdata{$key} = $value; 
    }                                
  }                                                   

# Send response ----------------------------------------------------------------------

print "Content-Type: text/html\n\n<html>";
print "<head><title>Web Server Response</title></head><div id='Panel'>";
print "The following data was received from a HTML form submission...<br>";
print "<table width='450' border='2' cellpadding='5'><col><col><tr><th>Name</th><th>Value</th></tr>";
foreach $key (sort (keys %formdata)){                      
print "<tr><td>$key</td><td>$formdata{$key}</td></tr>"; }    
print "</table></div></body></html>";

# End ----------------------------------------------------------------------------------

Wait… why are you referencing Perl at C:/Perl/bin/perl? It should be /usr/bin/perl

Especially if you are putting this on a Linux server.

1 Like

That makes perfect sense now I look at it.

The file is exactly as supplied by the tutorial I was following (an ‘In Easy Steps’ JS book). What is not made clear at any point are the pre-requisite steps needed to get a Perl file to run. Looking at that path, it would seem that Windows is assumed, and that the student has Perl installed on their device - I’ve never used Perl before, and have never encountered it in all the time I’ve worked on Windows machines, which must be 25+ years now.

I’ll edit that file when I get home tonight and see how I get on, but the authors of that book need a bit of a kick up the backside I’d suggest.

I have never seen a shebang pointing to a drive.

TBH I’m a little surprised it would work at all.

What should be done is to add the path to the bin folder to the system PATH variable.

Which is what I’ve done in the past for getting PHP set up.

I wonder how many other people who’ve bought that book have given up at that point? There was an earlier exercise related to cookies that would work fine from the (in my case) D:\drive in IE, Edge, & Firefox, but would only run in Chrome & Opera if called from my Linux server. I’m guessing that was a security thing, but it was only trial and error got me round that, not the book.

Well I sorted the path out, but not the problem. The top of the file now looks like this, but I’m still getting the “End of script output before headers” message in the error log.

I get this if I run the file from the CL, which as previously only seems to indicate that I’ve used the wrong method to call it. The permissions look OK too.

Is it possible it doesn’t like being called from the browser, and specifically the JS file?

The JS files looks like this.

function init() {
  'use strict';
  var panel = document.getElementById( 'panel' );
  panel.innerHTML += 'Send Book Data';

  var form = document.getElementById( 'book');
  form.action = '../../../cgi-bin/echo.pl';
  form.method = 'POST';

  var title = document.getElementById( 'title' );
  title.size = '30';
  title.name = 'Book Title';
  title.value = 'JavaScript in Easy Steps';

  var author = document.getElementById( 'author' );
  author.size = '30';
  author.name = 'By Author';
  author.value = 'Mike McGrath';
}
document.addEventListener( 'DOMContentLoaded', init, false);

That sounds an awful lot like PHP’s “headers already sent” error message.

If you change the code by putting the print Content-type first (and commenting out the two places it is now) maybe that will help?

# in the directory configured for CGI scripts.

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

# Process request ----------------------------------------

  if ($ENV{'REQUEST_METHOD'} eq 'GET') 

Tried that, but no joy.

The error log looks like this - The errors at 18:17 were before I modified echo.pl, and the ones at 20:47 were after I modified things.

This is what running perl echo.pl from the CL gives.

You can see that it doesn’t like something about the way in which the file has been modified.

I would half expect to get undefine errors from the CLI since the script uses GET and POST.

Due to my rusty beginner level Perl I don’t know if it’s a code problem or a missing dependency, but the only way I could get it to work without getting a server error was to comment out a few regex lines.

    ($key, $value) = split(/=/, $pair);
    $key =~ tr/+/ /;
#    $key =~ s/%(..)/pack("c", hex($1))/eg;
    $value =~ tr/+/ /;
#    $value =~ s/%(..)/pack("c", hex($1))/eg;
#    $value =~ s/<!--(.|\n)*-->//g;  # ignore SSI

  • and I tweaked the HTML output a bit

Ends up neither.

I have trouble being able with copy-paste between the OS and VM guest and missed that I had typos (missing slashes in the match replace) in those lines.

That section of code deals with encoded strings. eg
pl?file=first+try.txt or pl?file=first%20try.txt
to first try.txt

I needed to go into the VMware Player guest and run

sudo apt-get install open-vm-tools 
sudo apt-get install open-vm-tools-desktop 

Here’s my current version of the script that works with GET vars

#!/usr/bin/perl

print "Content-type: text/html\n\n";
  if ($ENV{'REQUEST_METHOD'} eq 'GET') 
  {
    @pairs = split(/&/, $ENV{'QUERY_STRING'});
  }
  elsif ($ENV{'REQUEST_METHOD'} eq 'POST')
  {
    read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    @pairs = split(/&/, $buffer);
    if ($ENV{'QUERY_STRING'})
    {
      @getpairs = split(/&/, $ENV{'QUERY_STRING'});
      push(@pairs, @getpairs);
    }
  }
  else
  {
    print "Unrecognized method, Use GET or POST.";
  }
  foreach $pair (@pairs)
  {
    ($key, $value) = split(/=/, $pair);
    $key =~ tr/+/ /;
    $key =~ s/%(..)/pack("c", hex($1))/eg;
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("c", hex($1))/eg;
    $value =~ s/<!--(.|\n)*-->//g;
    if ($formdata{$key})
    {
      $formdata{$key} .= ", $value";
    }
    else
    {
      $formdata{$key} = $value;
    }
  }
print "<html><head><title>Web Server Response</title></head>\n";
print "<body><div>The following data was received from an HTML form submission.</div>\n";
print "<table><tr><th>Key</th><th>Value</th></tr>\n";
foreach $key (sort (keys %formdata))
{
  print "<tr><td>$key</td><td>$formdata{$key}</td></tr>\n";
}
print "</table></body></html>";