2009-02-01 16 views
8

में सी प्रोग्राम आउटपुट को पुनर्निर्देशित करने में समस्या मैंने सी में एक प्रोग्राम कोड किया है जो प्रिंटफ का उपयोग करके stdout पर संदेश भेजता है और मुझे आउटपुट को एक फ़ाइल (बैश से चलने) में रीडायरेक्ट करने में समस्या हो रही है।बैश

मैं कोशिश की है:

./program argument >> program.out 
./program argument > program.out 
./program >> program.out argument 
./program > program.out argument 

प्रत्येक मामले में, फ़ाइल program.out बनाई गई है, लेकिन यह खाली रहता है। बाद निष्पादन समाप्त होता है फ़ाइल आकार 0.

है अगर मैं पुनर्निर्देशन छोड़ देते हैं जब कार्यक्रम को क्रियान्वित करने:

./program argument 

फिर, printf का उपयोग कर stdout करने के लिए भेजे गए सभी संदेशों टर्मिनल में दिखाए जाते हैं।

मेरे पास अन्य सी प्रोग्राम हैं जिनके लिए मुझे आउटपुट को इस तरह रीडायरेक्ट करने में कोई समस्या नहीं है। क्या इसे प्रोग्राम के साथ ही करना है? बहस के साथ गुजर रहा है? समस्या को कहां देखना चाहिए?

सी कार्यक्रम के बारे में कुछ विवरण:

  • यह
  • stdin यह बीएसडी इंटरनेट डोमेन सॉकेट
  • यह का उपयोग करता है POSIX धागे
  • यह के लिए एक विशेष हैंडलर समारोह प्रदान करती है का उपयोग करता है से कुछ भी नहीं पढ़ता सिग्नेशन
  • का उपयोग करके SIGINT सिग्नल यह stdout के लिए कई नई लाइनें भेजता है (आप में से उन लोगों के लिए मुझे फ्लश करना चाहिए)

कुछ कोड:

int main(int argc, char** argv) 
{ 
    printf("Execution started\n"); 
    do 
    {   
     /* lots of printf here */ 
    } while (1); 
    /* Code never reached */ 
    pthread_exit(EXIT_SUCCESS); 
} 
+0

उत्पादन पुनर्निर्देशन के बिना एक ही कार्यक्रम स्क्रीन के लिए किसी भी उत्पादन का उत्पादन करता है? – womble

+0

मैंने इसे स्पष्ट करने के लिए प्रश्न संपादित किया है। धन्यवाद – mmutilva

उत्तर

14

फ्लशिंग के बाद नई पंक्तियां ही काम करता है जब एक टर्मिनल के लिए मुद्रण, लेकिन जरूरी नहीं कि जब एक फाइल करने के लिए मुद्रण। एक त्वरित Google खोज ने इस पृष्ठ को और जानकारी के साथ प्रकट किया: http://www.pixelbeat.org/programming/stdio_buffering/

"डिफ़ॉल्ट बफरिंग मोड" शीर्षक वाला अनुभाग देखें।

आपको बाद में Fflush (stdout) में कुछ कॉल जोड़ना पड़ सकता है।

आप setvbuf का उपयोग करके बफर आकार और व्यवहार भी सेट कर सकते हैं।

+1

कार्यक्रम समाप्त होने के बारे में क्या? तब stdout स्वचालित रूप से फ्लश नहीं किया जाना चाहिए? – mmutilva

+0

टर्मिनल और फ़ाइल में भेजने के बीच इस अलग-अलग stdout-buffer व्यवहार के बारे में जानकारी वाला कोई भी लिंक? – mmutilva

+0

मैंने अपनी प्रतिक्रिया में एक लिंक संपादित किया, ताकि सभी के लिए देखना आसान हो। प्रत्येक और फिर स्पष्ट रूप से फ़्लश करने के बजाय, आप setvbuf (मेरे उत्तर में भी लिंक) का उपयोग करके बफरिंग व्यवहार भी बदल सकते हैं। – gclj5

3

क्या प्रोग्राम रीडायरेक्ट की गई सामग्री की सामग्री को चेक करते समय समाप्त हो गया है? यदि यह अभी भी चल रहा है, तो आपका आउटपुट अभी भी चेन को कहीं भी बफर कर सकता है, इसलिए आप इसे फ़ाइल में नहीं देखते हैं।

इसके अलावा, और अन्य उत्तरों को अब तक प्रदान किया गया है, मुझे लगता है कि समस्या कोड का प्रतिनिधि उदाहरण दिखाने का समय है। बहुत सारी गूढ़ संभावनाएं हैं।

संपादित

नमूना कोड की नज़र से, आप मुद्रण हो रहा की एक अपेक्षाकृत छोटी राशि मिल गया है, तो आप उत्पादन बफर में पकड़ा कर रहे हैं। प्रत्येक लिखने के बाद फ्लश सुनिश्चित करें कि यह डिस्क पर चला गया है। आम तौर पर आप किसी पृष्ठ आकार के अनजान डेटा के लायक हो सकते हैं जो अन्यथा झूठ बोल रहा हो।

फ्लश की अनुपस्थिति में, केवल एक बार जब आप सुनिश्चित कर सकते हैं कि डिस्क पर सब कुछ है तो प्रोग्राम बाहर निकलता है। यहां तक ​​कि एक थ्रेड टर्मिनिंग भी ऐसा नहीं करेगा, क्योंकि आउटपुट बफर प्रति-थ्रेड नहीं हैं, वे प्रति-प्रक्रिया हैं।

+0

मैं इसे एक छोटे से कार्यक्रम में पुन: उत्पन्न नहीं कर सका और मूल कार्यक्रम इसे पोस्ट करने के लिए बड़ा है। मैं वैसे भी कुछ कोड दिखाने की कोशिश करूंगा। – mmutilva

6

बफर को फ्लश करना आमतौर पर exit() फ़ंक्शन द्वारा संभाला जाता है, जिसे आमतौर पर मुख्य() से return द्वारा स्पष्ट रूप से बुलाया जाता है। आप SIGINT को बढ़ाकर अपना प्रोग्राम समाप्त कर रहे हैं, और स्पष्ट रूप से डिफ़ॉल्ट सिगिन हैंडलर बफर को फ्लश नहीं करता है।

इस आलेख पर एक नज़र डालें: Applying Design Patterns to Simplify Signal Handling। लेख ज्यादातर सी ++ है, लेकिन दूसरे खंड में एक उपयोगी सी उदाहरण है, जो दिखाता है कि अपने कार्यक्रम से बाहर निकलने के लिए SIGINT का उपयोग कैसे करें।

क्यों टर्मिनल का व्यवहार फ़ाइल से भिन्न होता है, स्टीफर्स के Advanced Programing in the UNIX Environment अनुभाग 5.4 पर बफरिंग पर एक नज़र डालें। वह कहता है कि:

अधिकांश कार्यान्वयन निम्न प्रकार के बफरिंग के लिए डिफ़ॉल्ट हैं। मानक त्रुटि हमेशा unbuffered है। यदि वे टर्मिनल डिवाइस का संदर्भ लेते हैं तो अन्य सभी स्ट्रीम लाइन buffered हैं; अन्यथा, वे पूरी तरह से buffered हैं। इस पुस्तक में चर्चा की गई चार प्लेटफॉर्म मानक I/O बफरिंग के लिए इन सम्मेलनों का पालन करें: मानक त्रुटि unbuffered है, टर्मिनल डिवाइस के लिए खुली धाराएं लाइन buffered हैं, और अन्य सभी धाराओं को पूरी तरह से buffered हैं।
0

सुझाव:

  1. पुनर्निर्देशन एक फाइल करने के लिए stderr रूप में अच्छी तरह।
  2. अपनी आउटपुट फ़ाइल को पूंछ की कोशिश करें।
  3. एक फ़ाइल खोलें और अपने लॉगिंग को fprintf करें (यह जानने में सहायता के लिए कि क्या हो रहा है)।
  4. std * फ़ाइल हैंडल या 1-3 फ़ाइल डिस्क्रिप्टर के किसी भी मैनुअल बंद/डुप्लिकेशन/पाइपिंग के लिए खोजें।
  5. जटिलता को कम करें; printfs काम तक कार्यक्षमता के बड़े हिस्से काट लें। फिर जब तक यह फिर से टूटता है तब तक उन्हें पढ़ें। जारी रखें जब तक आप अपराधी कोड की पहचान नहीं करते।
0

बस रिकार्ड के लिए, पर्ल में आप का प्रयोग करेंगे:

use IO::Handle; 

flush STDOUT; 
autoflush STDOUT;