这是monitoring a Unix folder的Perl代码的样子:
#!/usr/bin/perl
use strict;
use warnings;
use File::Spec::Functions;
my $date = `date`; chomp $date;
my $datef = `date +%Y%m%d%H%M.%S`; chomp $datef;
my $pwd = `pwd`; chomp $pwd;
my $cache = catfile($pwd, "cache");
my $monitor = catfile($pwd, "monme");
my $subject = '...';
my $msg = "...";
my $sendto = '...';
my $owner = '...';
sub touchandmail {
`touch $cache -t "$datef"`;
`echo "$msg" | mail -s "$subject" $owner -c $sendto`;
}
while(1) {
$date = `date`; chomp $date;
$datef = `date +%Y%m%d%H%M.%S`; chomp $datef;
if (! -e "$cache") {
touchandmail();
} elsif ("`find $monitor -newer $cache`" ne "") {
touchandmail();
}
sleep 300;
}
chomp
看起来并不好。有什么办法可以做“自动冠军”吗? 最佳答案
那不要使用 shell 。
#! /usr/bin/perl
use warnings;
use strict;
use Cwd;
use POSIX qw/ strftime /;
my $date = localtime;
my $datef = strftime "%Y%m%d%H%M.%S", localtime;
my $pwd = getcwd;
结果略有不同:
date
命令的输出包含一个时区,但是上面的$date
的值不会。如果存在问题,请遵循下面Chas. Owens的出色建议,并使用strftime
获得所需的格式。你的子
sub touchandmail {
`touch $cache -t "$datef"`;
`echo "$msg" | mail -s "$subject" $owner -c $sendto`;
}
如果出现问题,将无声地失败。无声的失败是令人讨厌的。最好是按照以下方式编写代码:
sub touchandmail {
system("touch", "-t", $datef, $cache) == 0
or die "$0: touch exited " . ($? >> 8);
open my $fh, "|-", "mail", "-s", $subject, $owner, "-c", $sendto
or die "$0: could not start mail: $!";
print $fh $msg
or warn "$0: print: $!";
unless (close $fh) {
if ($! == 0) {
die "$0: mail exited " . ($? >> 8);
}
else {
die "$0: close: $!";
}
}
}
使用
system
而不是反引号可以更好地表达您的意图,因为反引号用于捕获输出。 system(LIST)
表单绕过 shell 程序,不必担心引用参数。在没有 shell 的情况下获得 shell 管道
echo ... | mail ...
的效果意味着我们必须自己做一些管道工作,但是与system(LIST)
一样,这样做的好处是不必担心 shell 引用。上面的代码使用多参数 open
:For three or more arguments if MODE is
'|-'
, the filename is interpreted as a command to which output is to be piped, and if MODE is'-|'
, the filename is interpreted as a command that pipes output to us. In the two-argument (and one-argument) form, one should replace dash ('-'
) with the command. See Usingopen
for IPC in perlipc for more examples of this.
上面的
open
派生了一个mail
进程,并且$fh
连接到其标准输入。父进程(代码仍在运行touchandmail
)与echo
一起扮演print $fh $msg
的角色。调用 close
会刷新句柄的I/O缓冲区以及一些额外的内容,这是因为我们如何打开它的:If the filehandle came from a piped
open
,close
returns false if one of the other syscalls involved fails or if its program exits with non-zero status. If the only problem was that the program exited non-zero,$!
will be set to 0. Closing a pipe also waits for the process executing on the pipe to exit—in case you wish to look at the output of the pipe afterwards—and implicitly puts the exit status value of that command into$?
and${^CHILD_ERROR_NATIVE}
.
关于perl - 我们在Perl中有自动冠军吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3694465/