Can someone please explain to me the very basics of getting perl to work on a server. Do I need a module on the server? If so where does it go? What do I name my files and where do they go?
From my understanding you need a module and it goes in the cgi-bin. I can't get a clear answer whether I name the file .pl or .cgi and when I put it in the cgi-bin I am getting a server error. I also have my permissions set to 777, so that shouldn't be the problem.
Please help! I just want to understand the how to get the very basic program working such as the one below. Thanks in advance!
#!/usr/bin/perl
require("cgi-lib.pl");
print &PrintHeader;
print "<html>";
print "<head><title>Hello world!</title></head>";
print "<body>";
print "<p>Hello world!</p>";
print "</body>";
print "</html>";
The latest version of cgi-lib.pl is dated 1999 and is very out of date. I suggest you use the CGI library instead, which is almost bound to be installed already on your server and is kept up to date (most recently on August 16 2012)
Your program should look like this:
#!/usr/bin/perl --
use strict;
use warnings;
use CGI ':standard';
print header;
print <<END;
<html>
<head><title>Hello world!</title></head>
<body>
<p>Hello world!</p>
</body>
</html>
END
Also note that you can run the program from the command line to see if it compiles and what output it generates. Once you have it working there you can move it to the server
The problem you are facing is you probably edited the source file on a Windows machine, which inserts a CR character before each linefeed. Make sure your code does not include any CRs or change the first line to:
#!/usr/bin/perl --
(that's two dashes and a space at the end of the line)
I concur with Dave Cross' comment, you need to tell your school that they are teaching you incorrectly. We in the Perl land are trying to get people to stop using the CGI module, and you are using its predecessor!
Here is a hello world app in a modern Perl framework, Mojolicious:
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => 'hello';
app->start;
__DATA__
## hello.html.ep
<html>
<head><title>Hello world!</title></head>
<body>
<p>Hello world!</p>
</body>
</html>
which you place into a file, (lets say test.pl). Install Mojolicious by running:
curl get.mojolicio.us | sh
and then start your app by running
perl test.pl daemon
Now you can visit http://localhost:3000 in your browser to see the result, no Apache, no cgi-bin needed!
A more fun example takes an "argument" with a default:
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/:name' => { name => 'world' } => 'hello';
app->start;
__DATA__
## hello.html.ep
<html>
<head><title>Hello <%= $name %>!</title></head>
<body>
<p>Hello <%= $name %>!</p>
</body>
</html>
Run this and try visiting http://localhost:3000/SilverNightaFall and see what it does!
This process of interpolating dynamic values into your HTML is known as templating, and it is much preferred these days (vs generating your entire HTML on each request).
Related
I have an HTML page in which I run a Perl script to get the value from HTML and writing it onto a file.
The problem I'm facing is that whenever I run the Perl script from the terminal as a root, the HTML page gets updated and runs fine, however if I try the same thing from HTML (using the Firefox browser) it fails. Perhaps because of a permission issue.
The following is an extract from my HTML page:
<div>
<form id="QA1_Insert" action="http://localhost/cgi-bin/person.pl" METHOD="POST" >
<table>
<tr>
<td class="columnLabel"> Name</td>
<td><input type="text" name="Name"></td>
<td class="columnLabel">Address:</td>
<td><input type="text" name="Description"></td>
</tr>
</table>
<input type="submit" value="submit"></form>
</div>
And here is my person.pl:
#!/usr/bin/perl -w
use strict;
use CGI ':standard';
use warnings;
use IPC::System::Simple qw(system capture);
use DBI;
use Cwd qw(chdir);
use FileHandle;
use Fcntl;
#sysopen (FILE ,"/root/info/person.txt",O_RDWR|O_CREAT,0755);
open (my $file,"<","/root/info/person.txt");
chmod 755,$file;
print FILE "<html><head></head><body><p>sakshi</p></body></html>";
close (FILE);
print
header(),
start_html(
-title => 'Command',
-text => '#520063'
);
print "Hello ";
print end_html();
I have tried creating it with sysopen, which doesn't work due to permission errors. I've also tried chmod. However, neither are working. Any suggestions on how to solve it would be appreciated.
Your web server does not run as the root user. That is correct. It should not do that. Since your file is in root's home directory, the web server user cannot access it. The chmod command will fail as well as the open.
Put your output file in a directory that the web server can access (and should access, unlike root's stuff) and it will work.
Note that you have a mix of lexical and global filehandles there. Decide which one you want. (You want $fh!) Also you are opening the file for reading with < and then you try printing to it. That will also not work.
You should check the return value of the open call. For example, you can say:
open my $fh, '<', $filename or die $!;
Check your web server's log file to see the errors. You are using strict and warnings, which is good, but you do not profit from the error messages if you do not look at them. It's probably saying 500 Internal Server Error. Your web server log has more information.
As an alternative, use CGI::Carp qw(fatalsToBrowser); will redirect them to the browser. Do not use this in production though.
Finally, note that CGI has been removed from the Perl core recently and that in recent releases of the CGI module on CPAN the HTML creation functions have been deprecated. They should not be used in new code.
I am new to CGI. I wrote a very complex module around perl, cgi, html and javascript. And it runs perfectly on command line. But I am not able to run it via browser. I went on debugging line by line from bottom of my script, only to find that the issue was around the HTML::TableExtract module itself. So to make it simple -
# perl -c test.cgi
test.cgi syntax OK
test.cgi
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TableExtract;
print "Content-type: text/html\n\n";
print <<htmlcode;
<html>
<head>
<title>CGI Perl Example</title>
</head>
<body>
<h1>CGI Perl Example</h1>
<p>CGI Perl Example</p>
</body>
</html>
htmlcode
This works perfectly on command line. But if I run it via Browser it just doesn't work. However, if I remove "use HTML::TableExtract" it works perfectly fine again - even in browser. The permissions are correctly set to 755.
Can someone please help me understand, what I am missing? And how can I fire it up from browser. How can I go about debugging this - My browser redirects me to page not found if I mention use HTML::TableExtract.
Note: Would like to point out one thing, this may be related to setting up some environment variable around HTML::TableExtract. When I first installed the module, there was an error which my hosting administrator helped resolve.
# ./test.cgi
Content-type: text/html
<html>
<head>
<title>CGI Perl Example</title>
</head>
<body>
<h1>CGI Perl Example</h1>
<p>CGI Perl Example</p>
</body>
</html>
Debugging perl CGI scripts
Add use CGI::Carp; to you script to make it report bugs to browser
[It produces http reply over STDOUT instead of default text over STDERR]
Most likely scripts executed from command line and from web server search for modules in different places e.g. due to different settings of PERL5LIB or PERLLIB environment variables.
WARNING
CGI::Carp may be a security threat in "production" version of cgi scripts.
It may provide crucial information to (potential) hackers.
Hi since other posts about this topic didn't do me much justice ( none of them seem to apply for Ubuntu 13.10, the version of Ubuntu I run), I decided to make another one. After running these lines ( a fellow stackoverflow member suggested running these)..
cd /etc/apache2/mods-enabled
sudo ln -s ../mods-available/cgi.load .
sudo ln -s ../mods-available/cgid.load .
sudo service apache2 restart
I placed the cgi files ( they are perl ones ) into my Apache2's cgi-bin # /usr/lib/cgi-bin. When typing localhost/cgi-bin/test.cgi, I got a 500 Internal server error. This is what the Server error log says..
[Fri Nov 22 21:23:29.045785 2013] [cgi:error] [pid 9559] [client 127.0.0.1:47663] AH01215: (8)Exec format error: exec of '/usr/lib/cgi-bin/test.cgi' failed
[Fri Nov 22 21:23:29.046720 2013] [cgi:error] [pid 9559] [client 127.0.0.1:47663] End of script output before headers: test.cgi
test.cgi looks like this...
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print <<HTML;
<html>
<head>
<title>A Simple Perl CGI</title>
</head>
<body>
<h1>A Simple Perl CGI</h1>
<p>Hello World</p>
</body>
HTML
exit;
Does anyone know what to do when then happens or have any suggestions? Thanks
EDIT:: Oddly enough, I got this cgi file i call test2.cgi to run.
#!/usr/bin/perl
use strict;
use warnings;
sub main {
print "Content-type: text/html\n\n";
print "Hello world\n\n";
print "What's your favorite food brah?\n";
}
main();
But the larger, more advanced cgi files that I need to work on wont run. These ones include stuff being printed out in html tags.
EDIT: Ignore any weird spacing in code. Its just how i copied it into the post.
Edit: Its not quite clear if there are extra spaces in the original code at the start of each line causing this issue, if not, ignore the rest of this! Thanks Amon
If you try running them from the console, it will help see immediately any errors. In this case...
Can't find string terminator "HTML" anywhere before EOF
#!/usr/bin/perl # make sure no space before # and this comment is not here
print "Content-type: text/html\n\n";
print <<HTML;
<html>
....
</body>
HTML
exit; # Make sure the HTML line before this has nothing either side of it
Basically, remove the single space before the #!/usr/bin/perl line as Amon points out if it exists, and also the closing HTML line should fix it (There shouldn't be anything surrounding the heredoc terminator, its not obvious there are spaces at the start of each line, but there are).
Sometimes when putting example code on a site, spaces etc may be introduced to help visually. I'm guessing some were introduced here that were copied into the code. Hard to spot!
I am using xampp 1.8.1 on windows 7 and want to use it for perl, but when i execute even the most easy hello world perl script it gives me an error 500. Does anybody know what i am doing wrong? this is my 'hello world script:
#!/usr/bin/perl
print "Hello World.\n";
Thanks in advance,
Change the shebang line to actually point to your Perl path, for example:
#!c:/Strawberry/perl/bin/perl.exe
You can quote it if necessary:
#!"c:/Program Files/Perl/perl.exe"
Note that in Perl you can always use forward slashes for directories even on Windows (and this is preferred because it avoids messy escaping issues).
On Windows, the path in the shebang line is not normally used for execution. Thus the convention is often to use #!/usr/bin/perl for compatibility with Linux. However, Apache actually does use this path, so it needs to be set accordingly.
The correct code is:
#!C:\xampp\perl\bin\perl.exe
# The above line is perl execution path in xampp
# The below line tells the browser, that this script will send html content.
# If you miss this line then it will show "malformed header from script" error.
print "Content-ype: text/html\n\n";
print "Hello world."
In xampp the perl execution path is C:\xampp\perl\bin\perl.exe
Also, you can save a perl file ith extension .pl, .pm, .cgi . But for browser use, I would prefer .cgi extension.
I think this would help you.
I'm unable to execute the HTML::Template function in the CGI.
I'm following a simple tutorial that I found here: http://metacpan.org/pod/HTML::Template
I created a new file on my server in the home path as test.tmpl.
I created a new file named frt.cgi ... (is that the issue here? should it be a different file extention??)
#!/usr/local/bin/perl -w
use HTML::Template;
# open the html template
my $template = HTML::Template->new(filename => '/test.html');
# fill in some parameters
$template->param(HOME => $ENV{HOME});
$template->param(PATH => $ENV{PATH});
# send the obligatory Content-Type and print the template output
print "Content-Type: text/html\n\n", $template->output;
I've modified the 1st line to reflect my host provided program path for perl. I don't know what the -w does I just know I've tried this with and without it. Also I've tried changing the code a bit like this:
use warnings;
use strict;
use CGI qw(:standard);
use HTML::Template;
I've searched...
https://stackoverflow.com/search?q=HTML%3A%3ATEMPLATE+&submit=search
https://stackoverflow.com/search?q=HTML%3A%3ATEMPLATE
https://stackoverflow.com/search?q=HTML%3A%3ATEMPLATE+PERL&submit=search
Yet I still do not see the answer.
I even searched google for .TMPL Encoding because I thought there may be some special type needed. Please help.
If you look in your server logs, you'll probably see an error message along the lines of:
HTML::Template->new() : Cannot open included file /test.html : file not found.
You need to provide the path on the file system, not a URI relative to the generated document.
First, you likely specified the wrong path - change /test.html to test.html.
Also, it is possible that there is no $ENV{HOME} variable in your system so set up flag die_on_bad_params to 0:
my $template = HTML::Template->new(
filename => 'test.html',
die_on_bad_params => 0,
);
Also, don't forget to mark your Perl file as executable by chmod 755.
Option -w makes Perl to enable warnings, so there is no point to write use warnings; afterwards.
You can check what Perl command line options do by using module B::Deparse, like this ($^W variable disables/enables warnings):
perl -w -MO=Deparse -e "print;"
This would print:
BEGIN { $^W = 1; }
print $_;