Perl CGI脚本执行报错:use CGI qw(:standard)语法错误排查
Perl CGI音乐搜索脚本语法错误排查与修复
问题背景
编写了用于音乐标题关键词搜索的Perl CGI脚本,服务器已安装CGI.pm模块,但执行时出现语法错误,需排查修复。
脚本代码
#! /usr/bin/perl -w # cgi59_inst_us01.pl < cgi52.pl # # The Search by WORD. # use CGI qw (:standard); $keyword_1 = param(keyword); $query_keyword = $keyword_1; ### Now, the above Sub-rountine returning _keyword_1 and _keyword_2 $query_length = length($query_keyword); use lib '.'; if( $query_length <= 1 ){ require 'cgi59_search_header.pl'; print "<font color=\"#ff0000\"> <br>"; print "Please type a word or words likely in a title of the music."; print "</font>"; require 'cgi59_search_footer.pl'; } else { $counter=0; ## Works as GLOBAL require 'cgi59_search_header.pl'; open (IN, "/var/www/db1/concatenate_distilled.txt") or die("error:$!"); while ( my $line = <IN> ){ ### _keyword_1 is ASCII and with [i]. while _keyword_2 is EXTENDED and no [i]. if ( ( $line =~ /$keyword_1/i ) || ( $line =~ /$keyword_2/ ) ) { ($Composer_Name, $Work_ID, $Performer_Name, $Performer_fn, $Category, $Op_No, $Title, $Dummy) = split ('\t', $_); # print qq { <tr><td><b> $Composer_Name : </b></td> }; # print qq { <td><b> $Op_No : </b></td> }; # print qq { <td><b> $Title </b></td></tr> }; print "<b>· </b><a href=\"http://110.3.33.130/cgi-bin/cgi60.pl?composer_name=$Composer_Name&work_id=$Work_ID\"> $Composer_Name, $Op_No, $Title </a><br>"; $counter++; } } close (IN); if($counter==0){ print "<font color=\"#ff0000\"> <br>"; print "No item found, try another search or wait until coming revision of database."; print "</font>"; } print "</table>"; ## Closing Output Table Formatter require 'cgi59_search_footer.pl'; } ## query_length check < word must be more than 2 chars > BIG IF_ELSE -loop closing.
错误信息
$ bash cgi59_inst_us02.pl cgi59_inst_us02.pl: line 7: syntax error near unexpected token `(' cgi59_inst_us02.pl: line 7: `use CGI qw (:standard);'
排查分析
- 执行方式错误:用
bash直接运行Perl脚本,导致bash尝试解析Perl语法(如use CGI qw (:standard);),自然出现语法错误。Perl脚本需由Perl解释器执行,而非bash。 - 脚本代码存在潜在问题:
$keyword_2未定义就用于正则匹配,会导致运行时警告/错误。- 循环中读取每行到
$line,但split操作使用$_,而$_并未在循环中更新,会导致分割错误内容。 - 未开启严格模式,全局变量易引发意外问题。
修复方案
1. 正确执行脚本
- 先给脚本添加执行权限:
chmod +x cgi59_inst_us02.pl - 用Perl解释器直接运行,或通过系统shebang自动调用:
perl cgi59_inst_us02.pl # 或添加权限后直接执行 ./cgi59_inst_us02.pl
2. 修正脚本代码问题
(1)添加严格模式与变量声明
在脚本开头添加:
use strict; use warnings;
同时为所有变量添加my声明,避免全局变量问题:
my $keyword_1 = param('keyword'); # param参数需加引号 my $query_keyword = $keyword_1; my $query_length = length($query_keyword); my $counter = 0;
(2)解决未定义变量问题
若$keyword_2是预留的扩展关键词,需先赋值;若暂时不需要该条件,可删除|| ($line =~ /$keyword_2/)部分,避免未定义变量报错。
(3)修正split的变量引用
循环中使用$line而非$_进行分割:
my ($Composer_Name, $Work_ID, $Performer_Name, $Performer_fn, $Category, $Op_No, $Title, $Dummy) = split /\t/, $line;
(注:split的分隔符用正则表达式更可靠,无需加单引号)
(4)验证shebang路径
确保shebang中的Perl路径正确,可通过which perl查看系统Perl路径,若路径不是/usr/bin/perl,需修改shebang行。
额外优化建议
- 使用CGI模块的
header()方法输出HTTP头部,避免内容输出异常:print header('text/html'); - 替换过时的
<font>标签为CSS样式,提升页面兼容性。 - 使用词法文件句柄替代旧式全局文件句柄,更安全:
open my $in_fh, '<', "/var/www/db1/concatenate_distilled.txt" or die("error:$!"); while (my $line = <$in_fh>) { # ... } close $in_fh;
内容的提问来源于stack exchange,提问作者Mitsuru Kido
相关产品推荐
相关产品推荐

