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

Hello everyone, I have code as follows within a perl cgi script

my $user = $q->param('user_id') my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=gmtime(time); $time = sprintf "%4d-%02d-%02d\t%02d:%02d\n", 1900+$year,$mon+1,$mday, +$hour+5,$min+30;#Displaying time my $regfile = 'report1.txt'; open(REG,">>$regfile") or die"Cannot open"; print REG "$user\t$time\n"; close(REG);

I want to print the user name and the time of running the cgi script to a file automatically as soon as I run the cgi script in a browser. But this is not working.Please help.

Replies are listed 'Best First'.
Re: Printing output of perl cgi to a file
by kcott (Archbishop) on Apr 01, 2014 at 09:11 UTC

    G'day Sabiha,

    "But this is not working."

    Well, you'll probably want to do something that makes it work.

    If you want our help with whatever that "do something" equates to, then providing us with information about "is not working" would be a good start.

    Please read the guidelines in "How do I post a question effectively?" and follow them in any future posts.

    -- Ken

      I have tried to write the code within a .pl file and have called that file from the cgi script as follows:

      system("perl /path/sys.pl");

      So that whenever I click on submit button in the browser, the .pl script should also run automatically.I am pretty much new to perl cgi

Re: Printing output of perl cgi to a file
by NetWallah (Canon) on Apr 01, 2014 at 15:03 UTC
    > I want to print the user name and the time of running the cgi script

    The "user name" of the person at the computer running the browser is not available by default, inside a server CGI program.

    If you need that, some sort of authentication or login process is required, that will capture ans store that information.

    Instead, you way want to use some easily available information, like the IP address of the client.

    CGI's remote_host() and remote_addr() are the best ways of getting that. You could try the remote_user() method, if you enable authentication.

    Your code:

    my $user = $q->param('user_id')
    expects the user name to come in via a query string. It would be unusual if this was required to be sent with every page the user visited.

            What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
                  -Larry Wall, 1992

Re: Printing output of perl cgi to a file
by Don Coyote (Hermit) on Apr 01, 2014 at 17:28 UTC

    Hi Sabiha

    There can be many reasons for things not working. Using the right modules can help you to determine this effectively. Within development CGI::Carp is very useful as it can report errors succintly. There are also modules designed to help with logging log4perl comes to mind, but there are plenty on cpan

    You have put code into a script which you import? You do not show this, but common errors are permissions and compilation. The former is a system error and the latter is a syntax error.

    Running the system command to call a perl script is likely unecessary in your case and leads to being unable to determine the type of error. Being a perl script there are many ways that the script can be called and run from within your script without reverting to opening a whole new process, and which will report your errors plainly. Not to mention the security concerns you are opening up by doing this.

    Firstly, place the external code to run into a subroutine within your script. Any compilation errors will show up straight away. If you have a lot of extra code that is used then put that subroutine into another file and import the file when it is needed.

    I show using the do approach, it is old and you are better off just to put the sub into the existing script, but it can show the errors through the die if... constructs. If I make the script to run unexecutable and unreadable chmod u-rx ./scriptname I will get a system error reported using do. Using require, will prevent namespace clashes which using do causes, but will only tell you it cannot find the file in the @INC path. Using require is preferred, and suggested.

    Two further points to do with security, untaint and filehandles. Cleanse your incoming paramaters by untainting them, so they are not used to gain access to serverside files/databases. And use $fh filehandle references and three argument open to handle them. That is seperate the mode >> from the filepath. For the same but not exclusive, reasons

    Try not to use system unless you really cannot help to, most utilities such as mkdir, chmod etc.. are already perl built-ins, but if you must, then I would suggest to construct the @systemcommand array whether the list is coming in from standin or even if I call it by itself from within the script, that way he using the same construct each time and need not worry about if they am applied the argument safest or many unever.

    Chances are you have left out the ending 1; in your importing script or, it is not executable/readable (permissions), also check your pathnames, are they full and correct paths?

    cgi script

    #!/usr/bin/perl -T use warnings; use strict; use CGI; use CGI::Carp qw(Fatalstobrowser Warningstobrowser); use CGI::Pretty; my $q = CGI->new; ... # my @runutil = qw(/usr/bin/util arg arg /path/arg/file ); # system { $runutil[0] } @runutil; my $taintedvar = $q->params('user_id'); my ( $safervar ) = ( $taintedvar =~ /^(\w+)$/ ); do '/lair/supervillain/X/Evil/ransomdemands.pl'; die 'syntax: ', $@ if $@; die 'system: ', $! if $!; my $thingtoprint = &show($safervar); open my $logfile, '>>', '/path/to/log'; print { $logfile } $thingtoprint,"\n"; close $logfile; ...

    ransomdemands.pl

    #!/usr/bin/perl use warnings; use strict; sub show{ my $name = shift; my ( $safername ) = ( $name =~ /^(\w+)$/ ); return 'six hundred zagillion $$ to the account of '.$safername; } # end on true if exporting script 1;

    I sincerely hope I have not added to your confusion here. Please do reply with the problem you find.