【问题标题】:ksh perl script.. if conditionksh perl 脚本.. 如果条件
【发布时间】:2013-03-11 14:42:44
【问题描述】:

朋友...

我有 bash 脚本,它每次都调用 perl 脚本并通过电子邮件发送日志文件结果。

我想更改我的 bash 脚本,使其仅在 perl 子例程行计数器 (rcounter++) 中有值时才发送电子邮件,而不是一直发送电子邮件。

关于如何更改 .ksh 文件的任何提示?

.ksh

#!/bin/ksh
d=`date +%Y%m%d`

log_dir=$HOME
output_file=log.list

if ! list_tables -login /@testdb -outputFile $output_file
   then    
      mailx -s "list report : $d" test@mail < $output_file
 fi

=======Below if condition also works for me=============================

  list_tables -login /@testdb -outputFile $output_file
 if ["$?" -ne "0"];
    then    
          mailx -s "list report : $d" test@mail < $output_file
 fi
========================================================================

Perl 脚本:list_tables

use strict;
use Getopt::Long;

use DBI;
use DBD::Oracle qw(:ora_types);

my $exitStatus = 0;
my %options = ()
my $oracleLogin;
my $outputFile;
my $runDate;
my $logFile;
my $rcounter;

($oracleLogin, $outputFile) = &validateCommandLine();

my $db = &attemptconnect($oracleLogin);

&reportListTables($outputFile);

$db->$disconnect;

exit($rcounter);


#---------------------------
sub reportListTables {

    my $outputFile = shift;

    if ( ! open (OUT,">" . $outputfile)) {
        &logMessage("Error opening $outputFile");
    }

    print OUT &putTitle;

    my $oldDB="DEFAULT";
    my $dbcounter = 0;
    my $i;

    print OUT &putHeader();

    #iterate over results
    for (my $i=0; $i<=$lstSessions; $i++) {
        # print result row
        print OUT &putRow($i);
        $dbCounter++;
    }

    print OUT &putFooter($dbCounter);
    print OUT "   *** Report End \n";

    closeOUT;
}


#------------------------------ 
sub putTitle {
    my $title = qq{
   List Tables: Yesterday
  --------------
};


#------------------------------
sub putHeader {
    my $header = qq{

   TESTDB
  ==============
    OWNER       Table   Created


};

#------------------------------
sub putRow {

    my $indx = shift;
    my $ln = sprintf "%-19s %-30s %-19s",
       $lstSessions[$indx]{owner},
       $lstSessions[$indx]{object_name},
       $lstSessions[$indx]{created};

return "$ln\n";

}

#------------------------------
sub getListTables {

    my $runDt = shift;
       $rcounter = 0;

    my $SQL = qq{
    selct owner, object_name, to_char(created,'MM-DD-YYYY') from dba_objects
    };

    my $sth = $db->prepare ($SQL) or die $db->errstr;

    $sth->execute() or die $db->errstr;;

    while (my @row = $sth->fethcrow_array) {
        $lstSessions[$rcounter] {owner}     =$row[0];
        $lstSessions[$rcounter] {object_name}   =$row[1];
        $lstSessions[$rcounter] {created}   =$row[2];

        &logMessage(" Owner:    $lstSessions[$rcounter]{owner}");
        &logMessage(" Table:    $lstSessions[$rcounter]{object_name}");
        &logMessage(" created:  $lstSessions[$rcounter]{created}");

        $rcounter++;
    }

    &logMessage("$rcounter records found...");

}

谢谢..

也很高兴在 perl 中包含 mail-x 部分,如果这样可以让生活更轻松..

【问题讨论】:

  • 您忘记插入变量 $SQL$rcounter(使用了裸字 SQL 和字符串 rcounter),并且您声明了 $rounter,但使用了 $rcounter。使用全局变量@lstSessions 很可能是一个非常糟糕的主意。使用use strict; use warnings;,并修复产生的警告/错误。
  • 感谢 TLP 的 cmets...实际上我在原始代码中使用了 $SQL、$rcounter、严格和警告...这是错字,因为我没有复制粘贴代码...如果记录计数器中有值,您知道如何仅通过 .ksh 发送电子邮件吗?
  • 我认为list_tables 是您的 Perl 脚本的名称,但您实际上并没有这么说。为什么不把所有的逻辑都放到 Perl 脚本中呢?如果 Perl 脚本在其他地方使用,也许您可​​以添加一个选项,告诉它适当地调用 mailx
  • 按照建议完成所有逻辑和文件名...谢谢

标签: perl ksh


【解决方案1】:

我不确定我是否正确理解了您的问题。另外,您的代码不完整。所以有一些猜测。


无法从调用方检查本地 Perl 变量的值。

但如果您的问题是 Perl 代码是否在日志文件中添加了任何内容,则解决方案很简单:删除“rcounter records found...”行(这无论如何都没有意义,因为它是 always 执行,查询是否返回结果)。然后,让 shell 脚本在调用 Perl 之前备份日志文件,然后创建一个 diff,只有在 diff 告诉您已将输出添加到日志文件时才发送邮件。

如果这对您没有帮助,请澄清问题。

编辑(来自下面的 cmets):

Shell 脚本编写并不难。现在,您的 Perl 脚本以以下结尾:

$db->($exitStatus);

这是您的退出代码。无论如何,您都不会在您的 shell 脚本中检查它,因此您可以将其更改为更有用的东西,例如写入的数据行数。一个原始的解决方案是通过在 Perl 脚本的顶部(例如,在 my $logFile; 之后)声明 $rcounter 全局(而不是 getListTables() 的本地)。然后你可以简单地替换上面的“exitStatus”行:

$rcounter;         

瞧,您的 Perl 脚本现在返回写入的数据行数。

在 Perl 中,返回码 0 被认为是失败,任何其他值都是成功。在 shell 中,情况正好相反——但幸运的是,您不必担心这一点,因为 Perl 知道这一点,并且在返回调用 shell 时会“反转”(否定)脚本的返回码。

所以你所需要的只是让邮件依赖于 Perl 的非零返回:

if list_tables -login /@testdb -outputFile $output_file
then
    mailx -s "list report : $d" test@mail < $output_file
fi

旁边的评论:在我看来,您的编程技能与您要解决的问题的范围不相称。如果从 Perl 向 bash 返回一个值会给您带来这么多麻烦,那么您可能应该将时间花在教程上,而不是从数据库获取输入和发送电子邮件。在尝试飞行之前先学会走路......

【讨论】:

  • Dev... 是的,我试图从子例程中检查变量 rcounter,您说无法从调用者那里检查...基本上我的输出文件从 3-4 个不同的子例程(页眉、页脚) 因此,如果创建了我从 $SQL 查询的任何表,则尝试通过电子邮件发送输出文件。
  • @Khallas301:我仍然不确定我是否理解。 cough 英语 cough... 您可以使用适当的返回码(发送邮件/不发送邮件)让您的 Perl 脚本退出,您可以在 shell 中检查脚本(变量$?)。如果由于某种原因这不起作用,您可以让 Perl 脚本生成一个“触发文件”,然后您的 shell 脚本检查触发文件是否存在 (if [ -f ${triggerfile} ]; then mailx ...; fi)。之后不要忘记删除触发器文件。
  • 请原谅我的英语,因为它不是我的母语,而且我评论的真的很匆忙,这使得句子更难理解;)......这个 perl 脚本的整个想法很简单...... 1。查询数据库并在日志文件中获取输出 2. 正确格式化日志文件(页眉/页脚) 3. 从 .ksh 和电子邮件输出日志文件调用 perl 文件......我目前的挑战是只有电子邮件输出日志文件,如果步骤 1 有任何行....
  • @Khallas301:英语也不是我的第一语言。我之前的评论对您的问题有帮助吗,还是还有什么不清楚的地方?
  • Dev..抱歉,回复晚了,刚刚迷失了这个帖子。我确实理解了你的建议,但老实说 shell 脚本对我来说太复杂了,我只是想保持简单而不涉及 diff,因为未来的计划是根据一周中的每一天分离输出文件。如果调用 perl 变量不是一个选项,那么将在 perl 脚本中包含电子邮件部分。
猜你喜欢
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
相关资源
最近更新 更多