alpal has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
I'm sure a couple people will laugh at me for not being able to figure this out, but I think I really am stuck. I'm trying to get my feet wet with cgi scripts and whatnot, so I say HEY, why not try making a counter for my webpage?? So I start. I made a really simple script that seems to work fine. It is:
#!/perl/bin/perl.exe open FILE, "visit.txt" or die "Screwed it up...Can't open for read..." +; $counter = <FILE>; close FILE; $counter = $counter + 1; open FILE, ">visit.txt" or die "Screwed it up...Can't open for write.. +."; print FILE $counter; close FILE; chomp ($counter); print "Content-type: text/html\n\n "; print "<br>$counter<br>";

I also have a visit.txt in the cgi-bin directory that stores just a single number.
I can actually go to http://localhost/cgi-bin/counter.pl and it displays the number of users, and every time you refresh the number goes up, which is exactly what I wanted!
The problem here, is that when I try to get the script to execute inside a webpage, nothing happens. In the html I used <!--#exec cgi="/cgi-bin/counter.pl"--> but the script never actually executes. I even tried using all combinations of the link, like "..cgi-bin/counter.pl" "counter.pl" etc.
I tried using <!--#echo var="blab labl ablabla bl ablabl ablabla"-->to see if any of these SSI commands will execute, and still nothing happens. I also tried the cmd one too, and still nothing. I tried naming the html as a .shtm as well, I read somewhere that that needed to be done, but still nothing.
I made the .htaccess file in my html directory, but apparently something still isn't configured correctly.
I just need to be able to have the script automatically execute as the page is loaded. This is sort of my window to getting more involved in perl and cgi scripts, but I can't get it to work! I've slaved for about 3 days now with no progress, so I thought the folks at perlmonks might be able to help or maybe just point me in the right direction.

Thanks!
Alan

Replies are listed 'Best First'.
Re: execute perl script in html
by Joost (Canon) on Dec 13, 2002 at 17:16 UTC
    Alan,

    Server-side includes might not be enabled on your server.

    Try contacting your hosting party (if you have them), or try looking at the apache SSI documentation if you know you have an apache server.

    -- Joost downtime n. The period during which a system is error-free and immune from user input.
Re: execute perl script in html
by fruiture (Curate) on Dec 13, 2002 at 17:29 UTC

    This doesn't concern your question (SSI is probably not enabled), but i think it is usefull to you:

    CGI Scripts running on a webserver must be able to work correctly when called parallely, because they will sometime. That's why your counter will break for simultaneous access to the file. You need to lock the file using flock() and you must keep that lock active between read and write.

    use Fcntl ':flock'; open my $fh, '+<' , 'visit.txt' or die "Error opening ..... : $!"; flock $fh , LOCK_EX; my $counter = <$fh>; ++$counter; seek $fh,0,0; truncate $fh,0; print $fh $counter close $fh; # ... output now

    See `perldoc -f flock` as well as `perldoc -f open`.

    --
    http://fruiture.de
Re: execute perl script in html
by valdez (Monsignor) on Dec 13, 2002 at 17:48 UTC

    Hi alpal, first try to rename your html file with .shtml extension, probably this is the extension used with the following directive listed in your httpd.conf:

    AddType text/html .shtml AddHandler server-parsed .shtml

    In your .htaccess file you should add:

    Options +Includes

    if not already set in your system wide Apache configuration file. Then use the following SSI command:

    <!--#include virtual="/cgi-bin/counter.pl" -->

    Note that the correct attribute is virtual and not cgi. There is an SSI howto on Apache site: Apache Tutorial: Introduction to Server Side Includes.

    Finally, there is a race condition in your script, what happens if two instances of your script try to access the counter.txt file at the same time? You would probably screw your counter. You need to lock counter.txt before using it. There is a nice introduction to this subject in perlopentut (perldoc -m perlopentut), with the piece of code you need:

    use Fcntl qw(:DEFAULT :flock); sysopen(FH, "numfile", O_RDWR | O_CREAT) or die "can't open numfile: $ +!"; # autoflush FH $ofh = select(FH); $| = 1; select ($ofh); flock(FH, LOCK_EX) or die "can't write-lock numfile: $!"; $num = <FH> || 0; seek(FH, 0, 0) or die "can't rewind numfile : $!"; print FH $num+1, "\n" or die "can't write numfile: $!"; truncate(FH, tell(FH)) or die "can't truncate numfile: $!"; close(FH) or die "can't close numfile: $!";

    HTH, Valerio

Re: execute perl script in html
by pfaut (Priest) on Dec 13, 2002 at 17:43 UTC

    #!/perl/bin/perl.exe makes this look like you're running on Windows. If you type counter.pl while in your cgi-bin directory, does your script execute? If not, you need to associate .pl files with the perl executable.

    Alternately, invoke perl with your script as an argument instead of trying to invoke your script directly.

    If you're not on Windows, make sure the execute bit is set on your script.

Re: execute perl script in html
by ibanix (Hermit) on Dec 13, 2002 at 16:58 UTC
    Hi Alan,

    It may be overkill for what you are doing, but the CGI module does a great job with this kind of work.

    I'm a little confused by your top line, #!/perl/bin/perl.exe; are you running this on a Windows system?

    Here's some small additions to niceify your code:
    use strict; use warnings; my $counter; open FILE, "visit.txt" or die "Screwed it up...Can't open for read: $! +\n; $counter = <FILE>; close FILE; $counter++; open FILE, ">visit.txt" or die "Screwed it up...Can't open for write: +$!\n"; print FILE $counter; close FILE;
    That should give you some better debugging options.

    Cheers,
    ibanix

    $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;
Re: execute perl script in html
by Anonymous Monk on Aug 15, 2015 at 18:29 UTC

    I've used Perl calls within HTML extensively on my Linux web site. The Perl scripts work when located anywhere in your web domain -- not just cgi-bin. I am able to use 'include virtual' and pass parameters to the script, which reads the parameters via the $ENV{'QUERY_STRING'} command.

    <html>
    <body>
    <!--#include virtual="/counter.pl?$param" -->
    </body>
    </html>

    However, I haven't been able to get 'include virtual' to work from inside a table, so I use 'exec cmd' instead, and forego parameter passing>/p>

    <html>
    <body>
    <table>
    <!--#exec cmd="/counter.pl" -->
    </table>
    </body>
    </html>