2010-09-12 14 views
8

這是我的Perl代碼看起來像monitoring a Unix folder我們有Perl中的autochomp嗎?

#!/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之後每一項任務看起來並不好。有沒有辦法做一個「autochomp」?

  • 我是Perl新手,可能沒有以最好的方式編寫代碼。歡迎任何關於改進代碼的建議。

+1

記住'chomp'可以採用一個列表:'chomp($ foo,$ bar,$ fubb)'也是有用的。 – FMc 2010-09-12 12:59:18

回答

14

Don那麼,不要使用外殼。

#! /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管道的效果echo ... | mail ...沒有shell意味着我們必須自己做一些管道工作,但好處 - 與system(LIST)一樣 - 不必擔心shell引用。上面的代碼使用許多參數的open

對於三個或更多個參數,如果MODE是'|-',文件名被解釋爲命令,其輸出將被管道,並且如果MODE是'-|',文件名被解釋作爲管道輸出給我們的命令。在雙參數(和單參數)形式中,應該用命令替換破折號('-')。有關更多示例,請參見Using open for IPC in perlipc

上述叉的open一個mail過程,並$fh被連接到它的標準輸入。父進程(代碼仍在運行touchandmail)與print $fh $msg執行echo的角色。調用close刷新手柄的I/O緩衝加一點點額外的,因爲我們是如何打開一看:

如果文件句柄從管道出來openclose返回false如果所涉及的其他系統調用的一個失敗,或者如果它的程序以非零狀態退出。如果唯一的問題是程序退出非零,$!將被設置爲0.關閉一個管道也等待在管道上執行的進程退出 - 以防希望事後查看管道的輸出,以及隱含地將該命令的退出狀態值放入$?${^CHILD_ERROR_NATIVE}

+0

感謝touchandmail建議。我正在考慮爲它添加一些錯誤處理。 – Lazer 2010-09-12 11:19:35

+0

什麼是'「| - 」'? – Lazer 2010-09-12 11:38:20

+0

@Lazer:'| -'打開一個管道,並將寫入文件句柄的所有內容重定向到新進程的標準輸入。 – 2010-09-12 13:12:16

5

嘗試把它變成一個功能:

sub autochomp { 
    my $command = shift; 
    my $retval = `$command`; 
    chomp $retval; 
    return $retval; 
} 

然後調用每個命令要執行,然後終日啃食。

4

在CPAN上使用DateTime或其他日期模塊而不是日期實用程序。

例如:

chomp (my $date = `date`); 

至於說更Perlishly,如果你發現自己重複同樣的:

use DateTime; 

my $dt = DateTime->now; 
print $dt->strftime('%Y%m%d%H%M.%S'); 
+1

對於'POSIX'這個日期,可能更容易/更輕量:'使用POSIX qw/strftime /; my $ date = strftime「%Y%m%d%H%M.%S」,localtime;' – Telemachus 2010-09-12 10:56:45

2

它可以使用以下語法在單行分配和chomp一遍又一遍地將它捲成一個子:

sub assign_and_chomp { 

    my @result; 
    foreach my $cmd (@_) { 
     chomp (my $chomped = $cmd); 
     push @result, $chomped; 
    } 
    return @result; 
} 

my ($date , $datef , $pwd) 

    = assign_and_chomp (`date` , `date +%Y%m%d%H%M.%S` , `pwd`); 
+0

['chomp'](http://perldoc.perl.org/functions/chomp.html)「返回從其所有參數中刪除的字符總數「,而不是結果。 – 2010-09-12 10:45:57

+0

@gbacon:這就是爲什麼我一個接一個地挑選標量 – Zaid 2010-09-12 11:36:16

+1

但是你的循環把'chomp'返回的值推到'@ result'上。 – 2010-09-12 12:15:21

6

更一般地,IO::All模塊確實提供autochomp相當於:

use IO::All; 
# for getting command output: 
my @date = io("date|")->chomp->slurp; 
#$date[0] contains the chomped first line of the output 

或者更一般地說:

my $fh = io("file")->chomp->tie; 
while (<$fh>) { 
# no need to chomp here ! $_ is pre-chomped 
} 

當然,對於date這種特定情況下,我會同意與其他答覆者相比,您可能更適合使用其中一個DateTime模塊,但如果您只是在文件中閱讀並且希望所有線路都是chomp編輯,然後IO::Allchomptie選項應用非常方便。

還要注意的是,chomp技巧在將句柄的全部內容直接拖拽到標量時(這只是它的實現方式)不起作用。

相關問題