PDA

View Full Version : Non-working perl/CGI script..


Jonhoo
12-07-2005, 02:25 PM
Hi :)

I've just made this perl/CGI script which is supposed to get quotes from a .txt file, and print a random one of them. When I run the file locally, it prints everything correct, content headers and all, but putting the file online, it just won't work.. I've made some other CGI pages such as a guestbook, which works just fine on the same server..

Any of you see the error?
Opening the page simply says: "Internal server error". (See http://jonhoo.web.surftown.nu/cgi-bin/quotes
According to my web servers error log, the error is "Premature end of script header"..


#!/usr/bin/perl
#quotes

use strict;
use warnings;
use diagnostics;
use CGI;
use CGI::Carp qw(fatalsToBrowser);

$cgi = new CGI();

chdir("cgi-bin");

print $cgi->header();
print qq{<html><head></head><body>};

$num = 0;
open DATA, "../Quotes.txt"
or die "Kan ikke aapne txt fil";
foreach (<DATA>)
{
@current[$num] = $_;
$num++;
}
close DATA;
$quotes = join "", @current;
@quotes = split /\n\n/gs, $quotes;

$index = rand @quotes;
@newquote = split /\n/, @quotes[$index];
$last = length(@newquote);
@newquote[$last] = "<br>".@newquote[$last];
$newquote = join "<br>", @newquote;
print qq{<br><br>$newquote<br><br>};
print qq{</body></html>};

mlseim
12-07-2005, 03:28 PM
I see this error on my browser:

Software error:

syntax error at quotes line 20, near "@current["
Global symbol "@current" requires explicit package name at quotes line 24.
syntax error at quotes line 30, near "@newquote["
Execution of quotes aborted due to compilation errors.

FishMonger
12-07-2005, 03:36 PM
Here's a more complete list of the errors.

[Wed Dec 7 07:31:51 2005] Perl-1.pl: Scalar value @current[$num] better written as $current[$num] at C:\temp\Perl-1.pl line 22.
[Wed Dec 7 07:31:51 2005] Perl-1.pl: Use of /g modifier is meaningless in split at C:\temp\Perl-1.pl line 27.
[Wed Dec 7 07:31:51 2005] Perl-1.pl: Scalar value @quotes[$index] better written as $quotes[$index] at C:\temp\Perl-1.pl line 30.
[Wed Dec 7 07:31:51 2005] Perl-1.pl: Scalar value @newquote[$last] better written as $newquote[$last] at C:\temp\Perl-1.pl line 32.
[Wed Dec 7 07:31:51 2005] Perl-1.pl: Scalar value @newquote[$last] better written as $newquote[$last] at C:\temp\Perl-1.pl line 32.
Content-type: text/html

[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$cgi" requires explicit package name at C:\temp\Perl-1.pl line 10.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$cgi" requires explicit package name at C:\temp\Perl-1.pl line 14.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$num" requires explicit package name at C:\temp\Perl-1.pl line 17.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@current" requires explicit package name at C:\temp\Perl-1.pl line 22.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$num" requires explicit package name at C:\temp\Perl-1.pl line 22.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$num" requires explicit package name at C:\temp\Perl-1.pl line 23.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$quotes" requires explicit package name at C:\temp\Perl-1.pl line 26.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@current" requires explicit package name at C:\temp\Perl-1.pl line 26.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@quotes" requires explicit package name at C:\temp\Perl-1.pl line 27.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$quotes" requires explicit package name at C:\temp\Perl-1.pl line 27.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$index" requires explicit package name at C:\temp\Perl-1.pl line 29.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@quotes" requires explicit package name at C:\temp\Perl-1.pl line 29.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@newquote" requires explicit package name at C:\temp\Perl-1.pl line 30.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@quotes" requires explicit package name at C:\temp\Perl-1.pl line 30.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$index" requires explicit package name at C:\temp\Perl-1.pl line 30.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$last" requires explicit package name at C:\temp\Perl-1.pl line 31.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@newquote" requires explicit package name at C:\temp\Perl-1.pl line 31.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@newquote" requires explicit package name at C:\temp\Perl-1.pl line 32.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$last" requires explicit package name at C:\temp\Perl-1.pl line 32.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@newquote" requires explicit package name at C:\temp\Perl-1.pl line 32.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$last" requires explicit package name at C:\temp\Perl-1.pl line 32.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$newquote" requires explicit package name at C:\temp\Perl-1.pl line 33.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "@newquote" requires explicit package name at C:\temp\Perl-1.pl line 33.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Global symbol "$newquote" requires explicit package name at C:\temp\Perl-1.pl line 34.
[Wed Dec 7 07:31:52 2005] Perl-1.pl: Execution of C:\temp\Perl-1.pl aborted due to compilation errors.
<h1>Software error:</h1>
<pre>Global symbol &quot;$cgi&quot; requires explicit package name at C:\temp\Perl-1.pl line 10.
Global symbol &quot;$cgi&quot; requires explicit package name at C:\temp\Perl-1.pl line 14.
Global symbol &quot;$num&quot; requires explicit package name at C:\temp\Perl-1.pl line 17.
Global symbol &quot;@current&quot; requires explicit package name at C:\temp\Perl-1.pl line 22.
Global symbol &quot;$num&quot; requires explicit package name at C:\temp\Perl-1.pl line 22.
Global symbol &quot;$num&quot; requires explicit package name at C:\temp\Perl-1.pl line 23.
Global symbol &quot;$quotes&quot; requires explicit package name at C:\temp\Perl-1.pl line 26.
Global symbol &quot;@current&quot; requires explicit package name at C:\temp\Perl-1.pl line 26.
Global symbol &quot;@quotes&quot; requires explicit package name at C:\temp\Perl-1.pl line 27.
Global symbol &quot;$quotes&quot; requires explicit package name at C:\temp\Perl-1.pl line 27.
Global symbol &quot;$index&quot; requires explicit package name at C:\temp\Perl-1.pl line 29.
Global symbol &quot;@quotes&quot; requires explicit package name at C:\temp\Perl-1.pl line 29.
Global symbol &quot;@newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 30.
Global symbol &quot;@quotes&quot; requires explicit package name at C:\temp\Perl-1.pl line 30.
Global symbol &quot;$index&quot; requires explicit package name at C:\temp\Perl-1.pl line 30.
Global symbol &quot;$last&quot; requires explicit package name at C:\temp\Perl-1.pl line 31.
Global symbol &quot;@newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 31.
Global symbol &quot;@newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 32.
Global symbol &quot;$last&quot; requires explicit package name at C:\temp\Perl-1.pl line 32.
Global symbol &quot;@newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 32.
Global symbol &quot;$last&quot; requires explicit package name at C:\temp\Perl-1.pl line 32.
Global symbol &quot;$newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 33.
Global symbol &quot;@newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 33.
Global symbol &quot;$newquote&quot; requires explicit package name at C:\temp\Perl-1.pl line 34.
Execution of C:\temp\Perl-1.pl aborted due to compilation errors.
</pre>
<p>
For help, please send mail to this site's webmaster, giving this error message
and the time and date of the error.

</p>

FishMonger
12-07-2005, 03:48 PM
If you use warningsToBrowser in addition to fatalsToBrowser and do a test run by executing the script on the command line, you will be able to catch problems like this.

use CGI::Carp qw(fatalsToBrowser warningsToBrowser);

$cgi = new CGI();

chdir("cgi-bin");

print $cgi->header();
warningsToBrowser(1);
print qq{<html><head></head><body>}; # this outputs a second set of headers

It's best not to use DATA as your filehandle because it's one of Perl's special filehandle names.

http://www.perl.com/doc/manual/html/pod/perldata.html

The tokens __END__ and __DATA__ may be used to indicate the logical end of the script before the actual end of file. Any following text is ignored, but may be read via a DATA filehandle: main::DATA for __END__, or PACKNAME::DATA (where PACKNAME is the current package) for __DATA__. The two control characters ^D and ^Z are synonyms for __END__ (or __DATA__ in a module). See the SelfLoader manpage for more description of __DATA__, and an example of its use. Note that you cannot read from the DATA filehandle in a BEGIN block: the BEGIN block is executed as soon as it is seen (during compilation), at which point the corresponding __DATA__ (or __END__) token has not yet been seen.

EDIT:
print $cgi->header();
print qq{<html><head></head><body>};

is better written as

print $cgi->header(), $cgi->start_html();

Jonhoo
12-07-2005, 04:44 PM
A bit embarassing, I had forgotten to sett the permissions correctly :P

You can now find the script in action @
http://jonhoo.web.surftown.nu/cgi-bin/quotes
or
http://quote.moo.no

Every time you update the page, it will show the number of visits, the total amount of quotes, and a brand new random quote :D

The error logs you all posted has been fixed now.. Simply because I added use strict; and had to define all my variables :)

Please post your thougths on this script :)

PS: Fully working code below:


#!/usr/bin/perl
#quotes

use strict;
use CGI;
use CGI::Carp qw(fatalsToBrowser);

my $cgi = new CGI();

chdir("cgi-bin");

print $cgi->header();
print qq{<html><head><title>Quotes</title></head><body>};

my @current;
my $allquotes;
my @quotes;
my $index;
my @newquote;
my $last;
my $quotetoprint;

open DATA, "../Quotes.txt"
or die "Kan ikke aapne txt fil";

@current = <DATA>;

close DATA;

$allquotes = join "", @current;
@quotes = split /\n\n/gs, $allquotes;
$index = int(rand @quotes);
@newquote = split /\n/gs, @quotes[$index];
$last = scalar(@newquote)-1;
@newquote[$last] = "<br><br>".@newquote[$last];
$quotetoprint = join "", @newquote;
$quotetoprint =~ s/\n/<br>/gs;
print qq{$quotetoprint};

open NUM, "../num.txt"
or die "Kan ikke aapne txt fil";

my $num = <NUM>;

close NUM;

$num++;

open NUM, ">../num.txt"
or die "Kan ikke aapne num fil";

print NUM $num;

close NUM;

my $numberofquotes = scalar(@quotes);
print qq{<p align="center">};
print qq{<br><br>This page has shown $num quotes};
print qq{<br>It currently contains $numberofquotes different quotes};
print qq{</p>};
print qq{</body></html>};

FishMonger
12-07-2005, 06:01 PM
I’m not sure if you’re asking us to critique the code or the format of your page.

Jonhoo
12-07-2005, 06:02 PM
Both :)

If you have any suggestions :)

Jon

FishMonger
12-07-2005, 06:39 PM
Additional Warnings:
Lines 31 and 33: “Use of /g modifier is meaningless in split”

Line 35: “Scalar value @newquotes[$last] better written as $newquotes[$last]” IMO, $newquotes[-1] is better.

If you change your input record separator to \n\n you can clean up some of your join/split statements. Here’s a starting point but would need to be tested/debugged.

open QUOTES, "../Quotes.txt"
or die "Kan ikke aapne txt fil";

{ local $// = “\n\n”;
@current = <QUOTES>;
close QUOTES; }

$index = int(rand @current);
@newquote = split /\n/, $quotes[$index];
$newquote[-1] = "<br><br>".$newquote[-1];
$quotetoprint = join "", @newquote;
$quotetoprint =~ s/\n/<br>/gs;

Jonhoo
12-07-2005, 09:30 PM
Done :D

It worked, however you had to use " instead of “ :)

Any more suggestions? :)

Jon

FishMonger
12-07-2005, 11:14 PM
This looks like a homework assignment, so before I go any further, you need to convince me that it isn't.

Jonhoo
12-08-2005, 06:36 AM
Nope, it isn't :)
It's just a little something I've made for fun and for learning CGI..

Over about a year now I've collected quotes from all around, and now that I'm learning Perl/CGI, why not make a script to share them :D

Dunno how I could convince you any more..

Jon