2010-09-12 9 views
8

यह मेरा पर्ल कोड monitoring a Unix folder के लिए कैसा दिखता है:क्या हमारे पास पर्ल में एक ऑटोचॉम्प है?

#!/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" करने का कोई तरीका है?

  • मैं पर्ल के लिए नया हूं और शायद इस कोड को सबसे अच्छे तरीके से नहीं लिखा होगा। कोड में सुधार के लिए कोई सुझाव स्वागत है।

+1

यह भी याद रखना उपयोगी है कि 'chomp' एक सूची ले सकता है:' chomp ($ foo, $ bar, $ fubb) '। – FMc

उत्तर

14

डॉन तब खोल का उपयोग नहीं करते हैं।

#! /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) फॉर्म खोल को छोड़ देता है और तर्कों को उद्धृत करने के बारे में चिंता करने की ज़रूरत है।

शैल पाइपलाइन echo ... | mail ... के प्रभाव के बिना खोल का मतलब है कि हमें खुद को नलसाजी काम का थोड़ा सा काम करना है, लेकिन लाभ- system(LIST) के साथ -इस को खोल उद्धरण के बारे में चिंता करने की आवश्यकता नहीं है। तीन या अधिक बहस के लिए

अगर मोड '|-' है, फ़ाइल नाम एक कमांड जो करने के लिए उत्पादन पहुंचाया जा रहा है के रूप में व्याख्या की है, और अगर मोड '-|' है, फ़ाइल नाम व्याख्या की है: कोड के ऊपर कई तर्क open का उपयोग करता है एक आदेश के रूप में जो हमें पाइप आउटपुट।दो-तर्क (और एक-तर्क) रूप में, किसी को आदेश के साथ डैश ('-') को प्रतिस्थापित करना चाहिए। इसके अधिक उदाहरणों के लिए Using open for IPC in perlipc देखें।

open कांटे के ऊपर एक mail प्रक्रिया, और $fh अपने मानक इनपुट से जुड़ा है। मूल प्रक्रिया (कोड अभी भी touchandmail चल रहा है) के साथ echo की भूमिका निभाता है। close क्योंकि हम इसे कैसे खोला थोड़ा अतिरिक्त कॉलिंग संभाल के आई/ओ बफ़र्स प्लस flushes:

filehandle यदि अन्य शामिल syscalls में से एक में विफल रहता है एक पाइप से open, close रिटर्न झूठी आया है या उसके कार्यक्रम अगर गैर-शून्य स्थिति के साथ बाहर निकलता है। यदि एकमात्र समस्या यह थी कि कार्यक्रम गैर-शून्य से निकला, $! को 0 पर सेट किया जाएगा। पाइप बंद करने से पाइप पर निष्पादित प्रक्रिया की प्रतीक्षा भी होती है-अगर आप बाद में पाइप के आउटपुट को देखना चाहते हैं- और निहित रूप से उस आदेश के बाहर निकलने की स्थिति मान $? और ${^CHILD_ERROR_NATIVE} में डालता है।

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 की इस विशेष मामले मैं सहमत होगा के लिए

+0

टचंडमेल सुझावों के लिए धन्यवाद। मैं इसके लिए कुछ त्रुटि प्रबंधन को शामिल करने की सोच रहा था। – Lazer

+0

'" | - "' क्या है? – Lazer

+0

@Lazer: '| -' एक पाइप खोलता है और नई प्रक्रिया के stdin में फ़ाइल हैंडल में लिखी गई सभी चीज़ों को पुनर्निर्देशित करता है। –

5

यह एक समारोह में डाल प्रयास करें:

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

और फिर प्रत्येक कमांड आप निष्पादित करने के लिए और फिर chomp चाहते हैं के लिए फोन है।

4

तिथि उपयोगिता के बजाय सीपीएएन पर दिनांक समय या दिनांक मॉड्यूल का उपयोग करें।

उदाहरण के लिए:

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/का उपयोग करें; मेरी $ date = strftime "% Y% m% d% एच% एम%%", लोकलटाइम; ' – Telemachus

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) "लौटाता है अपने सभी तर्कों से हटाए गए वर्णों की कुल संख्या, "चोटी वाले नतीजे नहीं। –

+0

@gbacon: यही कारण है कि मैं एक – Zaid

+1

द्वारा स्केलर्स को चोप्स कर रहा हूं लेकिन आपका लूप 'chomp' से '@ result' पर लौटाए गए मानों को धक्का देता है। –

6

आम तौर पर, IO::All मॉड्यूल वास्तव में एक autochomp के बराबर प्रदान करता है अन्य उत्तरदाताओं के साथ कि आप डेटटाइम मॉड्यूल में से किसी एक का उपयोग कर शायद बेहतर हो सकते हैं, लेकिन यदि आप बस एक फ़ाइल में पढ़ रहे हैं और अपनी सभी लाइनों कोबनाना चाहते हैंएड, IO::Allchomp और tie विकल्पों के साथ लागू बहुत सुविधाजनक है।

यह भी ध्यान दें कि chomp चाल काम नहीं करता है जब हैंडल की पूरी सामग्री को स्केलर में सीधे घुमाएगी (यह वैसे ही इसे लागू किया गया है)।

संबंधित मुद्दे