托管服务器配置为存储在操作过程中遇到的CGI/Perl脚本的错误日志。默认情况下,错误消息将发送到STDERR。
大多数HTTPD服务器将STDERR定向到服务器的错误日志,该日志存储托管在共享主机环境中的所有网站的信息。因此,个别网站所有者无法访问此文件。您可能希望保留与服务器错误日志不同的私有错误日志,或者可能希望将错误消息定向到Web浏览器。这可以通过在开发阶段相应地编写脚本来完成。
将错误消息发送到专用日志文件
carpout()函数可用于实现此目的。由于默认情况下不导出carpout(),因此必须将其明确导入为 –
使用CGI::Carp qw(carpout);
carpout()函数需要一个参数,该参数应该是用于编写错误的打开文件句柄的引用。它应该在CGI应用程序顶部的BEGIN块中调用,以便捕获编译器错误。
例如:
BEGIN {
use CGI::Carp qw(carpout);
open(LOG, “>>/domains/domain.com/logs/cgi-error.log”) or
die(“Unable to open cgi-error.log: $!\n”);
carpout(LOG);
}
此时,carpout()不会为您处理日志上的文件锁定。
将错误消息发送到Web浏览器
通过导入特殊的“fatalsToBrowser”子例程,可以将致命(死亡,忏悔)错误发送到Web浏览器:
使用CGI :: Carp qw(fatalsToBrowser);
死“无法打开日志文件”;
现在,致命错误将回显到浏览器以及日志文件。CGI :: Carp安排向浏览器发送最小的HTTP头,以便在早期编译阶段发生错误。非致命错误仍将仅定向到日志文件(除非使用carpout重定向)。
示例脚本
#!/usr/bin/perl -wT
# In the first line above, T causes Perl to check
# for “tainted” data, that is, data from outside the
# script (i.e. user input) that is going to be used
# to affect something else outside the script
# (i.e. writing to a log file)
# You can untaint data by parsing it for unwanted
# characters then saving it to another variable.
# If you are having trouble with a script, try removing
# the T switch to see if that is the problem.
# The w switch in the first line causes warnings about
# script syntax to be printed, if there are any.
# This script does 2 things:
#
#1. It directs fatal errors to the browser,
# so when the script is invoked via the Web,
# a meaningful error message is returned.
# This is useful when developing a script;
# but should be disabled when the script
# is made publicly available.
#
# 2. It will direct any error message the script
# generates to an error log that resides in
# the user‘s home directory. The file must
# already exist and be “other” writeable.
# Notice that the following is enclosed in a BEGIN { }
# block that causes it to execute before the rest of
# the script is read.
# This block should be placed in the main script,
# as near the top as practical. Do not place it in
# subroutines or libraries. Always test
# subroutines thoroughly before placing them
# in libraries.
BEGIN {
# define an error log in YOUR home directory
# this is an example where the
# home directory is /domains/domain.com/
my $error_log = “/domains/domain.com/logs/cgi-error.log”;
# “my” in the line above makes the variable $error_log
# local so it only has meaning inside this block.
# See your text for more on variable scope.
# load the CGI::Carp module;
# fatalsToBrowser directs fatal errors to the browser
# carpout is for directing errors to the error log
use CGI::Carp qw(fatalsToBrowser carpout);
open (LOG,“>>$error_log”) ||
die “couldn’t open log file: $!”;
carpout(LOG);
# open(。..) is used to open a file.
# >> means the new input will be appended what‘s
# already in the file.
# LOG is a nickname (properly called a “file handle”)
# that is given to the file so it is easy to refer to
# it later, i.e. carpout(LOG) sends the error
# message to the file with the nickname LOG
# || means “or” (as in do this or that)
# die means stop executing the program. You can add
# a message in quotes after the die command.
# $! is a special variable that contains the current error info
}
# The following line will cause an error.
# It is a call to a sub-routine that does not exist.
# After you have tried this script and received the error message,
# comment out the following line so no error occurs
# and “Hello world!” is printed.
&non_existent_subroutine();
print <<EOT;
Content-type: text/html\n\n
<HTML>
<BODY>
Hello world!
EOT
print “</BODY></HTML>”;