My Perl application (in BlueHost hosting) is generating some errors. This error can be shown in the Main Error Log of BlueHost (which is shared):
/var/log/domlogs/error_log
I don't understand how my errors appears in that file, because in my code I am not referencing it anywhere. How does this process works? Is there any way to avoid my errors appear in that file?
You can redirect STDERR yourself without needing an external module:
use strict;
use warnings;
use autodie;
BEGIN {
open my $fh, '>>', 'myerror.log';
close STDERR;
*STDERR = $fh;
}
warn "Hello world";
die "Bye world";
The above script closes the default STDERR and opens my own. It waits to close until after the open command is called just in case there is some error with the file we're trying to log to.
Log file will report:
Hello world at scratch.pl line 11.
Bye world at scratch.pl line 13.
This line solved my problem:
use Tie::STDERR '>> /home/user/public_html/project/log/error_log.log';
I had to install the perl module:
Tie:STDERR
Information taken from:
http://www.adelton.com/perl/Tie-STDERR/
Related
I can redirect STDERR from the command line by doing:
perl myscript.pl 2> err.txt
How can I do this within the script so that the person running the script doesn't have to do it?
This is what I do
open STDERR, '>', "$errfile"
or warn "Cannot redirect STDERR to $errfile: $!";
If this is in a library, call carp instead of warn. That requires use Carp;, for core module Carp.
In case the STDERR stream will need to be restored first save it, as shown in open.
Very new to Perl. Running Perl on Padre and Windows 10 OS.
The script from my book is written for Unix. I don't know how to correct it so that it works with Windows.
Here is the script as written in my book (FOR UNIX):
use warnings;
#write to a file with a filehandle. Sriptname: file.handle
my $file="/home/jody/ellie/perl/newfile";
open(my $fh, ">", $file) || die "Can't open newfile: $!\n";
print $fh "hello world.\n";
print $fh "hello world again.\n";
At the command line
$perl file.handle
$cat newfile
the output should be looking like this:
hello world.
hello world again.
I made the following changes but with no success
use warnings;
#Write to a file with a filehandle. Scriptname: file.handle
my $file='C:\newfile.txt';
open (my $fh, ">", $file) || die "Can't open newfile: $!\n";
print $fh "hello world.\n";
print $fh "hello world again.\n";
When I run script I get the following output:
can't open newfile: permission denied**
When I run the script with debug I get the following information:
uncaught exception for user code
can't open newfile: permission denied
at handlingfiles.pl line 5
press any key to continue
What am i doing wrong?
As #choroba mentioned in a comment, C:\newfile.txt will [try to] write to the Windows root directory (e.g. C:\). So, you probably want just newfile.txt.
Cygwin: If you're using the perl that comes with cygwin, you can probably use /home/jody/newfile.txt as this perl supports the POSIX file syntax. If you installed cygwin at (e.g.) D:\cygwin, then the /home directory will end up in D:cygwin\home. Note you do ls /home to see what users have been defined.
Otherwise, if you want a full path, what is the full path for your .pl script. Obviously, you could write to that directory.
Side note: I've been writing perl for many years and on those rare occasions when I do use it on Windows, I vastly prefer using the cygwin version [that also has many scripts, tools, etc. and functions like a POSIX environment]. YMMV
Perl is asked to open the file for writing, so that is what it does. On Windows, normal users cannot write to the root directory of a drive, and Windows rejects its request. Try something like C:\Users\User\My Documents\newfile.txt.
I am trying to redirect my STDOUT and STDERR to some file. I am successful with that to some extent. But i am not able to understand one thing in the below code.
#!/usr/bin/perl
open (STDOUT,">/var/tmp/outfile") or die "problem : $!";
open (STDERR,">>/var/tmp/outfile") or die "problem : $!";
print "$_\n" foreach (1..10);
sdsdf; # buggy line inserted wantedly
I have inserted the last line assuming that perl would throwout an error and that would be redirected to the file but its not happening . My program does not throughout any error onto the screen nor to the outfile. Please help me understand this behavior.
The sdsdf is not generating any errors (if you use strict then you'll see some compile time errors), that's why you are not seeing any messages. Try this:
use warnings;
use strict;
open (STDOUT,">outfile1") or die "problem : $!";
open STDERR, ">&STDOUT";
print "$_\n" foreach (1..10);
die("aaaa"); # buggy line inserted wantedly
Also in your code you are opening the same file twice, this might cause some problems. In the above we first redirect the stdout to a file then redirect stderr to stdout.
Without use strict;,
sdsdf;
is the same as
"sdsdf";
That's one of the reasons you always want to use use strict; use warnings;. Let's start by adding that.
So you want to log all output including compile-time errors to a file. Well, that's not going to happen by redirecting STDERR after your code has been compiled. The best way to do this is from outside your program.
script.pl >/var/tmp/outfile 2>&1
but it can be done from within your program.
#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
open(STDOUT, '>', '/var/tmp/outfile')
or die("Can't redirect STDOUT: $!\n");
open(STDERR, '>&', \*STDOUT)
or die("Can't redirect STDERR: $!\n");
}
print "$_\n" foreach (1..10);
sdsdf; # Syntax error
I want to add some logs to my CGI scripts with Perl code like this:
open(LOG, ">/path/to/my.log") or die;
print LOG "Some content...\n";
close(LOG);
However, logs are never written to my log file, while the scripts are still correctly handling requests.
I'm not very familiar with Apache, CGI and Perl, so gurus please shine a light.
It is probably a permission problem. The script's runner (probably user: apache, httpd or nobody) has no permission to write to the file. However, to be sure, you need to check what $! contains. Also try checking Apache's ErrorLog file when the script is run.
I would rewrite your code as:
use CGI::Carp qw( croak );
open my $log, '>', '/path/to/my.log' or croak "Error opening file: $!";
print $log "Some content...\n";
close $log;
The problem has been solved: changes to my Perl script take effect only after restarting Apache. Not sure why it behaves like this because I am thinking Perl is an interpreted language and it can be modified on the fly...
I run my Perl script (gettotal.pl) and it works fine. I managed to get the sum of TOTAL.txt and append the output value to test.txt. But when I run it inside shell script (test.sh) I got this error:
Too many arguments for open at /home/daily/scripts/per_NODE_HR/gettotal.pl line 29, near ""$dir")"
Execution of /home/daily/scripts/per_NODE_HR/gettotal.pl aborted due to compilation errors.
What is the difference between running it manually (./gettotal.pl) and running it inside shell script? Simple yet still confusing for me:-)
gettotal.pl
#!/opt/perl/bin/perl-w
use strict;
my $sum;
open(FH,"/home/daily/scripts/per_NODE_HR/date.txt");
chomp (my #date = <FH>);
my $path = "/home/daily/output/per_NODE_HR/$date[0]/TOTAL.txt";
open(FILE,"$path") or die "Unable to open $path: $!";
my #hits = <FILE>;
$sum=sum($#hits);
print "TOTAL = $sum";
print "\n";
sub sum {
if ($_[0] == 0) {
return $hits[0];
}
return $hits[$_[0]] + sum($_[0]-1);
}
my $dir = "/home/daily/output/per_NODE_HR/$date[0]/test.txt";
open(OUT,'>>', "$dir") or die "Cannot open $dir: $!";
print OUT "TOTAL: $sum";
close OUT;
close FILE;
close FH;
shell script
#!/bin/sh
perl /home/daily/scripts/per_NODE_HR/gettotal.pl
The error you're getting suggests that your system perl is a truly ancient version... The three-argument form of open was added in perl 5.6.0 (released March 22, 2000), so a complaint about your open having too many arguments would seem to indicate that you're passing your code to a 5.5.x or older perl. Try perl -v on the command line to see what version the system perl is.
As for how to resolve this, call it in your shell script with just /home/daily/scripts/per_NODE_HR/gettotal.pl instead of perl /home/daily/scripts/per_NODE_HR/gettotal.pl and it will get passed to /opt/perl/bin/perl-w as specified in the shebang (#!) line, just like it does when you run it manually with ./gettotal.pl.
Incidentally, you might also want to add a use warnings along with use strict instead of relying on your code being run with perl -w. If you use perl gettotal.pl, warnings will not be enabled.
Almost certainly, perl != /opt/perl/bin/perl.
Try which perl.