.sh脚本如果数字> 100发送带有号码的电子邮件

时间:2016-05-27 20:00:31

标签: perl shell sh

我正在尝试编写一个查看.txt文件的脚本,并确定第一个数字是否大于或等于100.如果是,则发送电子邮件,如果不是,则不执行任何操作。

以下是.txt文件的示例

vi output.txt

108

由于该数字超过100,因此应发送一封电子邮件:

电子邮件示例

You have 108 errors

这是我到目前为止所得到的:

#!/bin/bash

filename = '/home/tted01/SPOOL/error.txt'

while read -r line
do
    id = $(cut -c-3 <<< "$line")
    echo $id >> /home/tted01/SPOOL/output.txt
done < "$filename"

mailx -s "ERRORS" ted.neal@gmail.com -- -f ted.neal@gmail.com < /home/tted01/SPOOL/output.txt
sleep 5

exit 0

我无法弄清条件语句以及如何解析变量。

2 个答案:

答案 0 :(得分:2)

这是一个简单的Perl脚本。由于我们需要同时发送消息和文件,因此问题中的示例将更改为 attach 文件。这看起来适合于一个小文本文件,无论如何都会在正文中讨论这些内容。使用mailx还有其他方法可以执行此操作,请参阅系统上的man mailx

use warnings;
use strict;

my $file = '/home/tted01/SPOOL/error.txt';
my $mark = 100;

# Slurp the whole file into a variable
my $cont = do {
    open my $fh, '<', $file  or die "Can't open $file -- $!";
    local $/; 
    <$fh>;
};

# Pull the first number
my ($num) = $cont =~ /^(\d+)/;

if ($num > $mark) 
{
    my $body = "You have $num errors.";
    my $cmd_email = "echo $body | " .
        "mailx -a $file -s \"ERROR\" ted.neal\@gmail.com";
    system($cmd_email) == 0  or die "Error sending email -- $!";
}

由于这显然是一个足够小的文件,因此可以一次性读入变量。我们通过一个简单的正则表达式提取文件中的第一个数字。 (“数字”被理解为连续数字,最多为数字以外的任何数字。)

电子邮件命令是通过system执行的,在Perl中使用sh。如果执行命令没有错误,Perl的system将返回0,因此我们对此进行测试。请注意,这并不告诉我们命令本身是如何做的,只是它运行正常。如果需要,所有这些都可以通过其他方式完成 - 可以使用反引号(qx)来获取输出,并在命令中使用可能的流重定向来获取错误。此外,如果需要,可以显式调用bash

这是如何撰写邮件的另一个选项。如果文件确实很小,您可以将其内容包含在邮件正文中。

此代码段之前和之后的所有内容都保持如上。

my ($num) = $cont =~ /^(\d+)/;

chomp($cont);
my $body = "You have $num errors. Log file: $file. Content: $cont";

my $cmd_email = "echo $body | mailx -s \"ERROR\" ted.neal\@gmail.com";

请注意,我们必须小心新行,因此chomp并且邮件正文中没有换行符。所以这推动了一点。

如果日志文件可能太大或者可能不太大,您可以检查行数并且可能包括前5或10(并附加文件),或者包括上面的整个文件(如果足够小)。这在Perl中很容易处理。你可以进一步完善这一点。最后,如果事情发展并变得复杂,您可以将Perl模块用于电子邮件。

出现了一个非常合理的问题 - 如果数字不是文件中的第一个,该怎么办?例如,如果它是第二行的第一件事怎么办?

如果文件很小,人们仍然可以将其读入上面的变量,并使用(更复杂的)正则表达式来查找模式。例如,如果数字是第二行的第一件事

my ($num) = $cont =~ /.*\n(\d+)/;

该模式直接与\n匹配换行符,并捕获其后的第一个数字。由于没有/s或此类修饰符,因此换行符与.不匹配,因此贪婪的.*会根据需要停在第一个换行符处。

然而,随着更复杂的要求出现,这会变得非常快。因此,只需逐行处理。

# Instead of reading all content into $cont
open my $fh, '<', $file  or die "Can't open $file -- $!";

my $num;
while (my $line = <$fh>) 
{
    if ($. == 2) {                    # $. is number of lines read
        ($num) = $line =~ /^(\d+)/;
        last;                         # we are done, quit the loop
    }
}
# Process the same way as above

我们使用Perl的内置特殊变量之一$.,其中包含从(最后访问的)文件句柄中读取的行数。见Special Variables in perlvar。请注意,该行在<>处读取,因此当我们处理第一行时,循环$.内部为1等。正则表达式是相同的,这是一个解释上面缺少。

匹配$line =~ m/.../始终返回匹配的列表,因为它可以匹配多次,因此我们使用()在列表中“捕获”它。由于这里只有一个,因此使用一个变量就足够了,因此($num)m/可能会被省略,您通常会这样看,=~ /.../

这是一个简单的条件,它是第二行。但是这样你也可以使用更复杂的东西。

答案 1 :(得分:1)

这里有bash脚本解决方案: -

#!/bin/bash
filename = '/home/tted01/SPOOL/error.txt'

while read -r line;
do
id =`echo $line`
    if [ $id -gt 100 ]; then
        mailx -s "You have $id errors" ted.neal@gmail.com  < /home/tted01/SPOOL/output.txt
    fi
sleep 5
done < filename