我们在Perl中有自动冠军吗? [英] Do we have an autochomp in Perl?
问题描述
这是监视Unix文件夹:
#!/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
看起来并不好.有什么办法可以做自动斩"?To do a
chomp
after every assignment does not look good. Is there some way to do an "autochomp"?我是Perl的新手,可能没有以最好的方式编写此代码.欢迎提供任何改进代码的建议.
I am new to Perl and might not have written this code in the best way. Any suggestions for improving the code are welcome.
推荐答案
那么不要使用外壳.
#! /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
获取所需的格式.The result is slightly different: the output of the
date
command contains a timezone, but the value of$date
above will not. If this is a problem, follow the excellent suggestion by Chas. Owens below and usestrftime
to get the format you want.您的子
sub touchandmail { `touch $cache -t "$datef"`; `echo "$msg" | mail -s "$subject" $owner -c $sendto`; }
如果出现问题,
会静默失败.无声的失败是令人讨厌的.最好是按照
will fail silently if something goes wrong. Silent failures are nasty. Better would be code along the lines of
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)
表单绕过了外壳程序,不必担心引用参数.Using
system
rather than backticks is more expressive of your intent because backticks are for capturing output. Thesystem(LIST)
form bypasses the shell and having to worry about quoting arguments.在没有外壳的情况下获得外壳管道
echo ... | mail ...
的效果意味着我们必须自己做一些管道工作,但是与system(LIST)
一样,这样做的好处是不必担心外壳引用.上面的代码使用了许多参数open
:Getting the effect of the shell pipeline
echo ... | mail ...
without the shell means we have to do a bit of the plumbing work ourselves, but the benefit—as withsystem(LIST)
—is not having to worry about shell quoting. The code above uses many-argumentopen
:对于三个或更多参数,如果MODE为
'|-'
,则将文件名解释为将输出传递到的命令,如果MODE为'-|'
,则将文件名解释为将输出传递给我们的命令.在两个参数(和一个参数)形式中,应使用命令替换破折号('-'
).请参见将open
用于perlipc中的IPC 更多示例.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
的代码)与print $fh $msg
一起充当echo
的角色.调用close
会刷新句柄的I/O缓冲区以及一些额外的内容,这是因为我们打开了它:The
open
above forks amail
process, and$fh
is connected to its standard input. The parent process (the code still runningtouchandmail
) performs the role ofecho
withprint $fh $msg
. Callingclose
flushes the handle's I/O buffers plus a little extra because of how we opened it:如果文件句柄来自管道
open
,则如果所涉及的其他系统调用之一失败,或者其程序以非零状态退出,则close
返回false.如果唯一的问题是程序退出时非零,则$!
将设置为0.关闭管道还等待管道上执行的进程退出-如果您希望随后查看管道的输出—并将该命令的退出状态值隐式地放入$?
和${^CHILD_ERROR_NATIVE}
.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中有自动冠军吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!