2010-10-29 15 views
8

मैं जानबूझकर एक रनटाइम त्रुटि पाने के लिए एक कोड लिखा है:stdout बारे में/stderr पुनर्निर्देशन

int main() 
{ 
int a=5; 
printf("Hello World\n"); 
printf("a=%s\n", a); 
} 

यह देता है:

$ ./error.o 
Hello World 
Segmentation Fault 
$ 

अब, क्रम त्रुटियों रिकॉर्ड करने के लिए, मुझे क्या करना:

$ ./error.o > so.txt 
$ ./error.o &> soe.txt 

लेकिन दोनों फाइलें खाली हैं। क्यूं कर?

संपादित करें:

मैं वास्तव में दूरदराज के संकलन और एक सी कार्यक्रम के निष्पादन के लिए एक स्क्रिप्ट लिख रहा हूँ। उत्तरों से मुझे लगता है कि Segmentation Fault प्रोग्राम का त्रुटि आउटपुट नहीं है। तो, क्या उस आउटपुट को कैप्चर करने का कोई तरीका है? साथ ही, कार्यक्रम सिर्फ एक नमूना है, इसलिए मैं कथन नहीं जोड़ सकता। क्या लाइन-बफरिंग रीडायरेक्शन के साथ किसी भी अन्य तरीके से किया जा सकता है?

+0

% s गलत है। – Nyan

+0

@ न्यान: मैं जानबूझ कर सेग-गलती प्राप्त करने के लिए कर रहा हूं। मैं निष्पादन त्रुटियों को कैप्चर करने के लिए एक स्क्रिप्ट लिख रहा हूं, इसलिए यह मेरी स्क्रिप्ट पर भविष्य के संभावित इनपुट की नकल करता है। – lalli

+1

आपने पुनर्निर्देशित फ़ाइलों के लिए लाइन बफरिंग को सक्षम करने के तरीके के बारे में प्रश्न संपादित किया है। मैंने जानकारी जोड़ने के लिए अपना जवाब अपडेट किया। – jjrv

उत्तर

10

so.txt खाली है क्योंकि क्रैश से पहले stdout flushed नहीं मिला था इसलिए buffered सामग्री खो गई थी। यदि आप जोड़ते हैं: fflush (stdout); printf-command के बीच, इसमें अपेक्षित टेक्स्ट होगा।

आपकी soe.txt में "सेगमेंटेशन फॉल्ट" संदेश भी गायब है क्योंकि यह आपके प्रोग्राम द्वारा नहीं, बल्कि आपके प्रोग्राम के आउटपुट का हिस्सा नहीं था, जो आपके प्रोग्राम के आउटपुट का हिस्सा नहीं था।

यदि आप कोड को संशोधित नहीं कर सकते हैं, तो आप प्रोग्राम को मूर्ख बनाकर लाइन बफरिंग चालू कर सकते हैं ताकि यह सोच सके कि यह एक tty पर प्रिंट कर रहा है।

#!/bin/sh 
./error.o 

फिर chmod एक + x error.sh करते हैं और लिनक्स पर इस तरह इसे कहते: स्क्रिप्ट error.sh बनाएं

script soe.txt -c ./error.sh 

या ओएस एक्स पर इस तरह:

script soe.txt ./error.sh 

सटीक आउटपुट कुछ हद तक सिस्टम-निर्भर है लेकिन शायद इसमें "हैलो वर्ल्ड" और "सेगमेंटेशन फॉल्ट" दोनों शामिल होंगे।

उचित # अंतर्निहित रेखाएं जोड़ने और मुख्य से मूल्य लौटने पर भी विचार करें।

+0

फ़ाइल में 'सेगमेंटेशन फॉल्ट' कैप्चर करने का कोई तरीका है? क्या मैं बैश के अंदर एक और बैश चला सकता हूं और ऐसा कर सकता हूं? – lalli

+0

हां, उत्तर अद्यतन किया गया। – jjrv

+0

आह, धन्यवाद ..... – lalli

7

क्योंकि सेगमेंटेशन गलती गंभीर है। बफर फ्लश नहीं होते हैं, आपकी प्रक्रिया हिंसक रूप से बंद हो जाती है।

जब आप रीडायरेक्शन के बिना दौड़ते हैं तो पाठ को देखने का कारण यह है कि मानक आउटपुट लाइन buffered है (आईएसओ सी जनादेश देता है कि पूर्ण बफरिंग केवल तभी उपयोग की जाती है जब डिवाइस को एक इंटरैक्टिव नहीं होने के लिए निर्धारित किया जा सके)। दूसरे शब्दों में, जब भी यह एक नई लाइन देखता है तो यह फ्लश हो जाएगा, और यह से पहले आपके अमान्य डी-रेफरेंसिंग होता है।

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

हालांकि इस के लिए समर्थन कार्यान्वयन से परिभाषित, आप एक विशिष्ट फ़ाइल हैंडल सेट कर सकते हैं लाइन _IOLBF मोड के साथ setvbuf का उपयोग करके बफ़र किया जा रहा है, कुछ की तरह:

setvbuf (stdin, NULL, _IOLBF, BUFSIZ); 
main() के शुरू में

- यह बचाता है प्रत्येक आउटपुट लाइन fflush पर टाइपिंग की पर्याप्त मात्रा।

+0

क्या पुनर्निर्देशन के साथ लाइनों को बफर करने का कोई तरीका है? – lalli

+0

धन्यवाद, अनुमान है कि मुझे शेड्यूलर को बेवकूफ बनाना होगा ... – lalli

+0

@lalli, हाँ, आप कर सकते हैं, मैंने अक्सर यह किया है कि हर जगह 'fflush() 'रखने से बचें। 'Setvbuf()' पर अद्यतन देखें। – paxdiablo

3

मुझे लगता है कि यह यह करना चाहिए: पूर्णांक के लिए

echo ./error.o | sh > error.txt 
+0

ओह, यह मदद करता है, धन्यवाद .. – lalli

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