我们在Perl中有自动冠军吗? [英] Do we have an autochomp in Perl?

查看:108
本文介绍了我们在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 use strftime 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. The system(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 with system(LIST)—is not having to worry about shell quoting. The code above uses many-argument open:

      对于三个或更多参数,如果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 Using open for IPC in perlipc for more examples of this.

      上面的open派生mail进程,并且$fh连接到其标准输入.父进程(仍在运行touchandmail的代码)与print $fh $msg一起充当echo的角色.调用 close 会刷新句柄的I/O缓冲区以及一些额外的内容,这是因为我们打开了它:

      The open above forks a mail process, and $fh is connected to its standard input. The parent process (the code still running touchandmail) performs the role of echo with print $fh $msg. Calling close 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆