You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>·&nbsp;&nbsp;&nbsp;</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);'

排查分析

  1. 执行方式错误:用bash直接运行Perl脚本,导致bash尝试解析Perl语法(如use CGI qw (:standard);),自然出现语法错误。Perl脚本需由Perl解释器执行,而非bash。
  2. 脚本代码存在潜在问题:
    • $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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:34:53