2011-06-20 3 views
9

मैं अपने कोड को किसी विशेष छवि को आउटपुट करने से रोकने के लिए STDOUT को बंद करना चाहता हूं जिसे मुझे और गणना के लिए आवश्यक है लेकिन मेरे वेब पेज पर नहीं चाहिए।पर्ल में STDOUT को बंद और फिर से खोल सकता है?

तो मैं STDOUT को बंद करना चाहता हूं, मुझे अपने कोड के साथ क्या करना है, फिर एक वेब पेज पर सामान आउटपुट करने के लिए STDOUT को फिर से खोलें। (एक फाइल करने के लिए नहीं)

मैं क्या करने की कोशिश की है:

close STDOUT; 
    # my code here 
    open STDOUT; 

यह काम नहीं करता ...

धन्यवाद

+2

आप उन चीजों को प्रिंट करने से क्यों नहीं रोकते जिन्हें आप मुद्रित नहीं करना चाहते हैं? – cjm

+0

मैं cgi_png() का उपयोग कर रहा हूं जो अनिवार्य रूप से ग्राफ – Italics

+0

प्रिंट करता है फिर इसके बजाय scalar_png का उपयोग करें। यह छवि देता है कि cgi_png प्रिंट करेगा (CGI शीर्षलेख को छोड़कर)। – cjm

उत्तर

9

आपकी समस्या से निपटने के कई तरीके हैं, और उनमें से कई को आपको STDOUT को बंद करने और अपने प्रोग्राम के मानक I/O चैनलों को फ्यूबर्स करने की आवश्यकता नहीं है।

उदाहरण के लिए, आप print के आउटपुट को अस्थायी रूप से कहीं भी आदेश देने के लिए (1-arg) select कमांड का उपयोग कर सकते हैं।

print $stuff_you_want_to_send_to_STDOUT; 

select(NOT_STDOUT); 
# now default print sends things to NOT_STDOUT. 
# This doesn't need to be a real filehandle, though you may get warning 
# messages if it is not. 
...; 
print $the_image_you_dont_want_to_go_to_STDOUT; 
...; 

select(STDOUT); 
# now print sends things to STDOUT agin 
print $more_stuff_you_do_want_to_go_to_STDOUT; 

आप किसी भी हैंडल बंद किए बिना रन-टाइम में *STDOUT ग्लोब पुन: असाइन कर सकते हैं।

*OLD_STDOUT = *STDOUT; 
print $for_STDOUT; 

*STDOUT = *NOT_STDOUT;  # again, doesn't need to be a real filehandle 
print $stuff_to_suppress; 

*STDOUT = *OLD_STDOUT;  # restore original STDOUT 
print $more_stuff_for_STDOUT; 
1

(पुनः) खुला STDOUT या STDERR के रूप में करने के लिए एक इन-मेमोरी फ़ाइल, इसे पहले बंद करें:

close STDOUT; 
    open STDOUT, '>', \$variable or die "Can't open STDOUT: $!"; 

से perl दस्तावेज़: http://perldoc.perl.org/functions/open.html आपके पास है: अपने बंद होने के बाद, ऐसा न करें। ऊपर खुला भी जूस

open STDOUT; 

यह धागा पर्ल भिक्षुओं में साथ काम करते हैं आप भी मदद कर सकता है चाहिए: http://www.perlmonks.org/?node_id=635010

2

documentation for open पढ़ें।

"यहां एक ऐसी स्क्रिप्ट है जो विभिन्न विधियों का उपयोग करके एसटीडीओयूटी और एसटीडीईआरआर को सहेजता है, पुनर्निर्देशित करता है और पुनर्स्थापित करता है"।

आप जो करना चाहते हैं वह STDOUT को बंद नहीं है, बल्कि इसे अस्थायी रूप से/dev/null पर रीडायरेक्ट करें।

5

एसटीडीओयूटी को बंद करना बुरा है क्योंकि यह मानता है कि यह हमेशा खुला रहता है। इसे /dev/null (यूनिक्स) या nul (विंडोज़) पर रीडायरेक्ट करना बेहतर है।

आप फ़ाइल वर्णनकर्ता रीडायरेक्ट करने के लिए चाहते हैं,

use Sub::ScopeFinalizer qw(scope_finalizer); 

{ 
    open(my $backup_fh, '>&', \*STDOUT) or die $!; 
    my $guard = scope_finalizer { open(STDOUT, '>&', $backup_fh) or die $!; }; 
    open(STDOUT, '>', '/dev/null') or die $!; 

    ... 
} 

तुम सिर्फ STDOUT रीडायरेक्ट करने के लिए चाहते हैं,

{ 
    local *STDOUT; 
    open(STDOUT, '>', '/dev/null') or die $!; 

    ... 
} 

तुम सिर्फ डिफ़ॉल्ट उत्पादन संभाल रीडायरेक्ट करने के लिए चाहते हैं,

use Sub::ScopeFinalizer qw(scope_finalizer); 

{ 
    open(my $null_fh, '>', '/dev/null') or die $!; 
    my $backup_fh = select($null_fh); 
    my $guard = scope_finalizer { select($backup_fh); }; 

    ... 
} 
+1

यदि यह स्पष्ट नहीं है, तो ब्लॉक के अंत में सबकुछ सामान्य रूप से सामान्य हो जाता है, इससे कोई फर्क नहीं पड़ता कि ब्लॉक कैसे निकला है। – ikegami

1

मैंने 2 तरीकों की जांच की:

    select
  1. के माध्यम से
  2. *OLD_STDOUT = * STDOUT के माध्यम से, और वे आम मामले में प्रयोग करने योग्य नहीं हैं देखते हैं।

कारण यह है कि इन 2 दृष्टिकोण केवल STDOUT को पुनर्निर्देशित करते हैं यदि "प्रिंट" या पर्ल स्क्रिप्ट में कुछ और उपयोग किया जाता है। लेकिन अगर आप "प्रणाली()" का उपयोग कॉल या सबस्क्रिप्ट कॉल करने, उनके उत्पादन मानक STDOUT गया वैसे = ((

देखने की मेरी बात, वास्तव में समाधान हो रहा है:।

#!/usr/bin/perl -w 
my $file1 = "/tmp/out.txt"; 
my $file2 = "/tmp/err.txt"; 
open my $oldSTDOUT, ">&STDOUT"; 
open OLDERR, ">&",\*STDERR; 
open(STDOUT, ">$file1") or print("Can't redirect stdout: to $file1 "); 
open(STDERR, ">$file2") or print("Can't redirect stderr: to $file2 "); 
print "THIS OUTPUT ISN'T GOT TO STANDARD OUTPUT\n"; 
system("pwd"); # this output isn;t got to standard output too, that is right! 
close(STDOUT); 
close(STDERR); 
open STDOUT, ">>&", $oldSTDOUT; 
open STDERR, ">>&OLDERR"; 
print "BUT THIS OUTPUT IS SEEN IN A STANDARD OUTPUT\n"; 

मैं जाँच इस समाधान और यह मेरे लिए काम किया

2

तुम इतनी तरह STDOUT को पकड़ने के लिए कुछ को लागू कर सकते हैं:।

sub stdout_of (&) { 
    my $code = shift; 

    local *STDOUT; 
    open STDOUT, '>', \(my $stdout_string = '') 
     or die "reopen STDOUT: $!"; 

    $code->(); 

    return $stdout_string; 
} 

और फिर इतना की तरह उपयोग:

my $stdout = stdout_of { print "hello world" }; 

stdout_of() के अंदर फ़ाइलहेडल को स्थानीयकरण करने से आप STDOUT को बंद करने और फिर से खोलने की चाल से बचने की अनुमति देते हैं।

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

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