首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未定义的子例程&在script>的第<行调用了package::subroutine

未定义的子例程&在script>的第<行调用了package::subroutine
EN

Stack Overflow用户
提问于 2013-12-10 17:43:52
回答 2查看 2.3K关注 0票数 0

我正在工作中调试这个脚本--老板说这个脚本是用来在Solaris上工作的,但是自从他们切换到linux后,它就停止工作了。我不得不用严格和警告重写它。当我运行它时,我得到了错误:

代码语言:javascript
复制
Undefined subroutine &Logging::openLog called at /path/to/script line 27

这是脚本(很好的一部分)

代码语言:javascript
复制
 1  #!/usr/local/bin/perl
 2
 3  unshift @INC, "/production/fo/lib";
 4  use strict;
 5  use warnings;
 6  use Sys::Hostname;
 7  use Getopt::Long qw(:config bundling auto_version);
 8  use File::Path;
 9
10  require "dbconfig2.pl";
11  require "logging2.pl";
12  require "hpov.pl";
13
14  # global variables
15  my $parseDate   = "";
16  my @fileList    = "";
17  my @transList   = "";
18  my $mLogDate    = "";
19  my $lHost                       = hostname;
20  my $corefiles_dir="/production/log/corefiles";
21  my $default_Threshold=90;
22
23  # do stuff
24
25  parseOptions();
26  Dbconfig::readconfigFile("$config");
27  Logging::openLog("$Dbconfig::prefs{logFile}","overwrite");
28  # msglog actions  TODO logs, compress only, data files
29          my $check_shdw=`ls -l /etc/motd | awk '{print \$11}' | grep 'motd.shdw'`; #Check if hostname is shadow
30          $check_shdw =~ y/\n//d; #remove new line if any
31  if ( $check_shdw eq "motd.shdw" )
32  {
33          Logging::printLog("INFO","Enviroment is Shadow, triggering core files compressing");
34          if (is_folder_empty($corefiles_dir)) {
35              print "Corefile Directory is EMPTY......! \n";
36          }
37          else {
38          gzip_corefiles() ; #Execute compress core files
39          }
40  }
41

脚本使用requies语句来调用脚本创建者构建的例程。对于此脚本的目的- dbconfig只是在一个配置文件中发出声音,并将它们分解为值。比如"$Dbconfig::prefs{ logfile }“等于一个日志文件位置/prod/logs/script.log --就是这样。

代码语言:javascript
复制
#!/usr/local/bin/perl

package Dbconfig;
#use warnings;
use DBI;
use DBD::Oracle;

%prefs          = "";
@$dbPrefs       = "";
$raiseError     = 0;
%startupItem    = "";

# readconfigFile(file) - read in a configuration file.
sub readconfigFile { 
    my $file = shift;
    if ( ! -e $file ) {
        $errorTxt   = "Error: $file does not exist.\n";
        $raiseError = 1;
    }
# read in the cfg variables
   open(CFGFILE,"<","$file") or die "Cannot open $file for reading: $!\n";
   while(<CFGFILE>) {
    chomp;    # kill newlines
    s/#.*//;  # ignore comments
    s/^\s+//; # ignore leading whitespace
    s/\s+$//; # ignore trailing whitespace
    next unless length;
    my($var,$value) = split(/\s*=\s*/, $_, 2);
    $prefs{$var} = $value;
   }
   close(CFGFILE);
}

然后是这个日志记录包。在脚本的第27行(错误出现的地方),我看到了一个" overwrite“调用,但在logging.pl包中没有看到任何引用覆盖的内容--但也不确定它是否重要。父脚本似乎不会写入任何日志文件。我甚至不确定文件句柄日志文件是否已创建。

代码语言:javascript
复制
#!/usr/local/bin/perl

 package Logging;

use File::Copy;
use warnings;
use strict; 

my $timestamp = "";
my $filestamp = "";

# openLog(logfile name) - opens a log file
sub openLog {
    my $file   = shift;
    my $rotate = shift;
 # force a rotation if it exists.
    if ( -e $file && $rotate eq "rotate" ) {
        print "Warning: $file exists.  Rotating.\n";
        rotateLog($file);
    }
    getTime(); 
    open(LOGFILE,">","$file") or warn "Error: Cannot open $file for writing: $!\n";
    print LOGFILE "[$timestamp] - Normal - Opening log for $file.\n"; 
}
# rotateLog(log file) - rotate a log.
sub rotateLog {
    my $file = shift;
    getTime();
    openLog("$file");
    print LOGFILE "[$timestamp] - Warning - Rotating $file to $file.$filestamp.log";
    closeLog($file);
    move($file,$file-"$filestamp.log");
    openLog($file);
}
time() - grab timestamp for the log.
sub getTime {
    undef $timestamp;
    undef $filestamp;
    ($sec,$min,$hour,$mday,$mon,$year) = (localtime(time))[0,1,2,3,4,5];
    $sec    = sprintf("%02d",$sec);
    $min    = sprintf("%02d",$min);
    $hour   = sprintf("%02d",$hour);
    $mday   = sprintf("%02d",$mday);
    $year   = sprintf("%04d",$year +1900);
    $mon    = sprintf("%02d",$mon +1);
    $timestamp  = "$mon-$mday-$year $hour:$min:$sec";
    $filestamp  = "$year$mon$mday$hour$min$sec";
}

只是想知道- logging.pl在第27行从dbconfig.pl调用某些东西有问题吗?例如,一个模块可以调用另一个模块的值吗?除了使用严格的和警告,以及大量的print语句之外,我不知道我的下一个调试步骤是什么。我不知道如何检查和查看日志文件文件句柄是否正在创建-如果它没有错误,我只能假设它是错误的。比如,我是否需要做一些额外的事情来让模块相互通信?

我不是一个脚本大王--只是我这一排中唯一能开始理解这些东西的人。

EN

回答 2

Stack Overflow用户

发布于 2013-12-10 18:33:08

不确定这是否会影响事情,但是...

1)包需要返回true,正常的程序是以一行结束文件:

代码语言:javascript
复制
1; 

以确保。

2) logger包中有一条注释,没有前导#,会导致编译失败:

代码语言:javascript
复制
time() - grab timestamp for the log.

3)这一行:

代码语言:javascript
复制
unshift @INC, "/production/fo/lib"; 

添加目录以搜索模块的路径,请确保logging2.pl文件确实在该位置(可能是,否则您会得到不同的错误,但值得仔细检查)

票数 3
EN

Stack Overflow用户

发布于 2013-12-11 19:03:13

那看起来没问题。

出于某些原因,尽管require "logging2.pl“可以工作(否则会出现错误),但其中的子例程无法加载和使用。与DBconfig2.pl的加载不同,DBconfig2.pl可以正常工作(否则对Dbconfig::readconfigFile()的调用将首先失败)。

我能看到的唯一区别是Logging2.pl中package命令的前导空格,尽管我认为这无关紧要。

是否可以尝试调用不带包前缀(Logging::)的openLog,以查看是否出于某种原因将其加载到main中,并在require语句后打印%INC的内容,以确保其正确加载?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20490924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档