Take the 2-minute tour ×

I was trying out an elementary Perl/CGI script to keep track of visitors coming to a web page. The Perl code looks like this:

use CGI':standard';
print "content-type:text/html\n\n";
#opening file in read mode
open (FILE,"<count.dat");
$cnt= <FILE>;
#opening file to write
print FILE $cnt;
print "Visitor count: $cnt";

The problem is that the web page does not increment the count of visitors on each refresh. The count remains at the initital value of $cnt , ie 1. Any ideas where the problem lies?

share|improve this question
Why include CGI if you never use it? –  TLP Nov 24 '11 at 19:57

4 Answers 4

up vote 6 down vote accepted

You never test if the attempt to open the file handle works. Given a file which I had permission to read from and write to that contained a single number and nothing else, the code behaved as intended. If the file did not exist then the count would always be 1, if it was read-only then it would remain at whatever the file started at.

More general advice:

  • use strict; and use warnings; (and correct code based on their complaints)
  • Use the three argument call to open as per the first example in the documentation
  • When you open a file always || handle_the_error_in($!);
  • Don't use a file to store data like this, you have potential race conditions.
  • Get the name of the language correct
share|improve this answer
Well thanks mate :). I'm not much of a Perl programmer and this is my first Perl CGI script :D. Btw, where is the count.dat file located? I could not find it in cgi-bin. I work with Ubuntu Linux. –  Amal Antony Nov 24 '11 at 19:22
@amal antony — The script expects it in the same place as the script (although cgi-bin is a very bad place to keep this sort of data) –  Quentin Nov 24 '11 at 19:24
or is safer than || –  Zaid Nov 24 '11 at 19:26
I got it fixed. It was a problem with the file permissions. Thanks again! –  Amal Antony Nov 24 '11 at 19:29
@Quentin the script expects it in the current working directory, which may, or may not (!), be the same directory as the script. –  tadmc Nov 25 '11 at 0:29

You will need to close the webpage and reopen it again. Just refreshing the page won't increment the count.

share|improve this answer

Here's an alternate solution that uses only one open() and creates the file if it doesn't already exist. Locking eliminates a potential race condition among multiple up-daters.

#!/usr/bin/env perl
use strict;
use warnings;
use Fcntl qw(:DEFAULT :flock);
my $file = 'mycount';
sysopen(my $fh, $file, O_RDWR|O_CREAT) or die "Can't open '$file' $!\n";
flock($fh, LOCK_EX) or die "Can't lock $file: $!\n";
my $cnt = <$fh>;
$cnt=0 unless $cnt;
seek $fh, 0, 0;
print ${fh} $cnt;
close $fh or die "Can't close $file: $\n";
print "Visitor count: $cnt\n";
share|improve this answer
This does not solve the problem or race conditions. More than one process could write and read at the same time. –  Matteo Nov 24 '11 at 20:19
@Matteo : Agreed and added. –  JRFerguson Nov 24 '11 at 20:37

A few potential reasons:

  • 'count.dat' is not being opened for reading. Always test with or die $!; at minimum to check if the file opened or not

  • The code is not being executed and you think it is

share|improve this answer

Your Answer


