क्या प्रगति रिपोर्ट / लॉगिंग जानकारी stderr या stdout पर है?


75

क्या कोई आधिकारिक POSIX, GNU, या अन्य दिशानिर्देश हैं जहां प्रगति रिपोर्ट और लॉगिंग जानकारी ("fing foo; foo done" जैसी चीजें) मुद्रित की जानी चाहिए? व्यक्तिगत रूप से, मैं उन्हें stderr पर लिखना चाहता हूं ताकि मैं stdout को रीडायरेक्ट कर सकूं और केवल प्रोग्राम का वास्तविक आउटपुट प्राप्त कर सकूं। मुझे हाल ही में बताया गया था कि यह अच्छा अभ्यास नहीं है क्योंकि प्रगति रिपोर्ट वास्तव में त्रुटियां नहीं हैं और केवल त्रुटि संदेश को stderr पर प्रिंट किया जाना चाहिए।

दोनों स्थिति समझ में आती हैं, और निश्चित रूप से आप जो भी कर रहे हैं उसके विवरण के आधार पर आप एक या दूसरे को चुन सकते हैं, लेकिन मैं यह जानना चाहूंगा कि क्या इसके लिए आमतौर पर स्वीकृत मानक है। मैं POSIX, GNU कोडिंग मानकों, या किसी भी अन्य ऐसे व्यापक रूप से स्वीकृत सर्वोत्तम प्रथाओं की सूची में कोई विशिष्ट नियम नहीं पा सका हूं।

हमारे पास कुछ समान प्रश्न हैं, लेकिन वे इस सटीक मुद्दे को संबोधित नहीं करते हैं:

तो, क्या कोई आधिकारिक नियम हैं जहां प्रगति रिपोर्ट और अन्य सूचनात्मक संदेश (जो कि कार्यक्रम के वास्तविक आउटपुट का हिस्सा नहीं हैं) को मुद्रित किया जाना चाहिए?


26
प्रिंटिंग स्पिनर और stdoutपरिणामों के साथ मिलकर परिणाम को बेकार बनाने का एक सुरक्षित तरीका है। यदि आपको कभी किसी अन्य कार्यक्रम में परिणामों को पाइप करने की आवश्यकता होती है, तो कार्यक्रम को स्पिनरों से परिणामों को अलग करने की आवश्यकता होगी। इसके अलावा, यदि आप आउटपुट को किसी फ़ाइल में रीडायरेक्ट करते हैं तो आप स्पिनरों को नहीं देख पाएंगे। IMHO।
सातु कटुरा

2
@SatoKatsura हाँ, मेरी भी यही राय है और इसीलिए मैं ऐसे स्टादर को छापता हूं। हालाँकि, मैं जिस कंपनी के लिए काम करता हूं, उसका सीटीओ महसूस करता है कि स्ट्रैडर पर छपाई इस बात का संकेत है कि कुछ गलत हुआ है। मैंने, बल्कि बोल्ड बनाया, दावा किया कि POSIX Way® स्ट्रैडर पर प्रिंट कर रहा है और उसने मुझे इस पर बुलाया। यह देखते हुए कि उसे मुझ पर 20 वर्षों का अनुभव है, मैं यह देखना चाहूंगा कि क्या मुझे किसी प्रकार की "आधिकारिक" गाइडलाइन मिल सकती है।
terdon

जैसा कि सातो कात्सुरा ने कहा, stdoutवास्तव में स्पिनरों और अन्य सूचनात्मक संदेशों को प्रस्तुत करने का एक सुरक्षित और सही तरीका है, लेकिन जैसा कि कई प्रोग्रामर कहते हैं, 'मौन स्वर्ण है। सब कुछ ठीक रहा तो आउटपुट कुछ भी नहीं। ' इसलिए वास्तव में, stderr का उपयोग हमेशा किया जाता है क्योंकि अस्पष्ट परिभाषा के कारण और stdout भी पाइप अनुक्रम को तोड़ सकता है। आधिकारिक गाइड के लिए
Se ven

6
@ मुझे लगता है कि आपको गलत समझा गया; सातो कह रहा है कि स्टडआउट का उपयोग करना असुरक्षित है ("परिणामों को बेकार बनाने के लिए सुरक्षित तरीका")।
स्टीफन किट

1
एक संभव एक आकार-फिट-सभी समाधान केवल stderrत्रुटि संदेशों की रिपोर्ट करने के लिए उपयोग किया जाएगा , सिवाय इसके कि जब एक --verboseझंडा का उपयोग किया जाता है, जिस बिंदु पर प्रगति रिपोर्ट भी शामिल हैं।
गौरव

जवाबों:


27

पॉज़िक्स इस प्रकार मानक धाराओं को परिभाषित करता है :

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

GNU सी पुस्तकालय इसी तरह मानक धाराओं में बताता है:

चर: फ़ाइल * stdout
मानक आउटपुट स्ट्रीम, जो प्रोग्राम से सामान्य आउटपुट के लिए उपयोग किया जाता है।

चर: फ़ाइल * stderr
मानक त्रुटि स्ट्रीम, जो प्रोग्राम द्वारा जारी किए गए त्रुटि संदेशों और निदान के लिए उपयोग किया जाता है।

इस प्रकार, मानक परिभाषाओं में "पारंपरिक / सामान्य आउटपुट" और "डायग्नोस्टिक / त्रुटि आउटपुट" से परे धारा के उपयोग के लिए बहुत कम मार्गदर्शन है। व्यवहार में, यह या तो इन धाराओं और फ़ाइलों और पाइपलाइनों दोनों को पुनर्निर्देशित करना आम है, जहां प्रगति संकेतक एक समस्या होगी। । कुछ सिस्टम आउटपुट के लिए भी निगरानी stderr करते हैं और इसे समस्याओं का संकेत मानते हैं। विशुद्ध रूप से सहायक प्रगति जानकारी इसलिए या तो स्ट्रीम पर समस्याग्रस्त है।

बिना किसी मानक धारा के बिना प्रगति के संकेतक भेजने के बजाय , यह पहचानना महत्वपूर्ण है कि प्रगति आउटपुट केवल इंटरैक्टिव धाराओं के लिए उपयुक्त है। इसे ध्यान में रखते हुए, मैं यह जाँचने के बाद ही प्रगति काउंटर लिखने की सलाह देता हूं कि क्या स्ट्रीम संवादात्मक है (उदाहरण के लिए isatty()) या जब कमांड लाइन विकल्प द्वारा स्पष्ट रूप से सक्षम किया गया है। यह प्रगति मीटर के लिए विशेष रूप से महत्वपूर्ण है जो टर्मिनल-अपडेट व्यवहार पर निर्भर करता है ताकि समझ में आए, जैसे%-अपूर्ण बार।

कुछ बहुत ही सरल प्रगति संदेशों के लिए ("शुरू एक्स" ... "एक्स के साथ किया") यह गैर-संवादात्मक धाराओं के लिए भी आउटपुट को शामिल करने के लिए अधिक उचित है। उस स्थिति में, विचार करें कि उपयोगकर्ता स्ट्रीम के साथ कैसे इंटरैक्ट कर सकते हैं, जैसे कि खोज करना grepया उसके साथ lessनिगरानी करना या निगरानी करना tail -f। यदि यह उन संदर्भों में प्रगति संदेशों को देखने के लिए समझ में आता है, तो वे उपभोग करना बहुत आसान हो जाएगा stdout


धन्यवाद, GNU गाइडलाइन मेरे बाद की चीज़ है। हालांकि, मुझे लगता है कि मेरा सवाल थोड़ा भ्रामक था। जब मैंने कहा "प्रगति रिपोर्ट" मैं की तरह दोनों चीजों की सोच रहा था N% doneकी तरह है और चीजें doing fooऔर foo done। उत्तरार्द्ध को हमेशा रखा जाना चाहिए क्योंकि उनका उपयोग डिबगिंग के लिए किया जाता है जब किसी फ़ाइल पर रीडायरेक्ट किया जाता है। तो यह जाँचने का आपका सुझाव कि क्या धारा अंतःक्रियात्मक है (हालांकि आम तौर पर एक बहुत अच्छा विचार है) लागू नहीं है।
terdon

स्पष्टीकरण के लिए धन्यवाद, यह "% पूर्ण" और हैश-मार्क प्रगति सलाखों की तरह केवल सामान से थोड़ा अलग है जो आप सॉफ्टवेयर में curlऔर जैसे देखते हैं yum। उस स्थिति में, मैं इस बारे में सोचूंगा कि क्या उपयोगकर्ता आउटपुट के माध्यम grepसे lessया इसी तरह के उपकरणों के साथ बातचीत करना चाहता है या नहीं।
ब्रैड सजोनी

ऊपर दिए गए स्पष्टीकरण को शामिल करने के लिए अद्यतित उत्तर।
ब्रैड सजोनी

71

POSIX मानक त्रुटि को परिभाषित करता है

डायग्नोस्टिक आउटपुट लिखने के लिए

यह केवल त्रुटि संदेशों तक इसके उपयोग को सीमित नहीं करता है। मैं प्रगति की जानकारी को डायग्नोस्टिक आउटपुट के रूप में मानूंगा, इसलिए यह मानक त्रुटि पर आधारित है।


8
एफडब्ल्यूआईडब्ल्यू, पायथन में, stdoutडिफ़ॉल्ट रूप से लाइन-बफ़र है जबकि अप्रभावित है stderr, इसलिए stderrप्रगति टेक्स्ट / बार / स्पिनर लिखने के लिए प्राकृतिक विकल्प है जिसमें एक नई रेखा नहीं है। (यदि आप इस तरह का पाठ लिखते हैं, तो आपको stdoutअपनी प्रगति आउटपुट कॉल को अव्यवस्थित करने की आवश्यकता stdout.flush()है, इसे दिखाई देने के लिए)।
PM 2Ring

12
@ PM2Ring कि पायथन के लिए विशिष्ट नहीं है, POSIX इस तरह धाराओं को परिभाषित करता है।
स्टीफन किट

4
@ PM2Ring: जब करने के लिए लिख stdout, आप फ्लश करने के लिए अपने पाठ भले ही जरूरत है एक नई पंक्ति को शामिल करता है, तो आप अपनी प्रगति रिपोर्ट वास्तव में जब पुनः निर्देशित वास्तविक समय में दिखाना चाहते हैं।

@ हर्किल आह, अच्छी बात। मैं पुनर्निर्देशन पर विचार नहीं कर रहा था।
बजे PM 2Ring

1
@Wtower, एह? अगर बाहर निकलने की स्थिति 0. है, तो Ansible स्टॉडर टेक्स्ट को निगलता है। यह दावा केवल झूठा है।
चार्ल्स डफी

10

POSIX शेल और यूटिलिटीज में "नैदानिक ​​जानकारी" के बारे में थोड़ा अधिक ठोस है , 1.4: उपयोगिता विवरण डिफ़ॉल्ट (जोर मेरा):

STDERR

STDERR अनुभाग उपयोगिता के मानक त्रुटि आउटपुट का वर्णन करता है। केवल वे संदेश जो उपयोगिता द्वारा जानबूझकर भेजे गए हैं, वर्णित हैं। मानक त्रुटि के लिए एक टर्मिनल का उपयोग मानक उपयोगिताओं में से किसी का कारण हो सकता है जो पृष्ठभूमि में उपयोग होने पर बंद करने के लिए मानक त्रुटि आउटपुट लिखते हैं। इस कारण से, अनुप्रयोगों को पृष्ठभूमि में रखी जाने वाली लिपियों में इंटरैक्टिव सुविधाओं का उपयोग नहीं करना चाहिए।

अधिकांश उपयोगिताओं के लिए नैदानिक ​​संदेशों का प्रारूप अनिर्दिष्ट है, लेकिन नैदानिक ​​और सूचनात्मक संदेशों की भाषा और सांस्कृतिक परंपराएँ जिनका प्रारूप POSIX.1-2008 की इस मात्रा से अनिर्दिष्ट है, LC_ESSAGES और [XSI] की सेटिंग से प्रभावित होना चाहिए [विकल्प प्रारंभ] ] एनएलएसपीएटीएच। [विकल्प समाप्ति]

मानक उपयोगिताओं का निर्दिष्ट मानक त्रुटि आउटपुट POSIX.1-2008 के इस वॉल्यूम द्वारा प्रदान किए गए को छोड़कर, POSIX.1-2008 के इस वॉल्यूम में परिभाषित पर्यावरण चर के अस्तित्व या मूल्य पर निर्भर नहीं करेगा।

डिफ़ॉल्ट व्यवहार : जब इस अनुभाग को "केवल नैदानिक ​​संदेशों के लिए मानक त्रुटि का उपयोग किया जाएगा" के रूप में सूचीबद्ध किया गया है, तो इसका मतलब है कि, जब तक अन्यथा नहीं कहा जाता है, तब तक नैदानिक ​​संदेश मानक त्रुटि पर भेजे जाएंगे जब निकास स्थिति इंगित करती है कि एक त्रुटि। हुई और उपयोगिता का उपयोग POSIX.1-2008 की मात्रा के अनुसार किया गया है।

जब इस खंड को "उपयोग नहीं किया गया" के रूप में सूचीबद्ध किया गया है, तो इसका मतलब है कि POSIX.1-2008 के इस वॉल्यूम में वर्णित उपयोगिता के अनुसार मानक त्रुटि का उपयोग नहीं किया जाएगा।

IANASL, लेकिन मैं व्याख्या करता हूं कि इसका मतलब यह है कि stderr का उत्पादन तभी होगा जब उपयोगिता एक त्रुटि निकास कोड लौटाएगी। चूंकि यह सफल निष्पादन के लिए घटनाओं का सामान्य कोर्स नहीं होना चाहिए, इसलिए जब तक कोई त्रुटि न हो (जब तक कि निश्चित रूप से अन्यथा निर्दिष्ट न हो, आदि) कोई भी प्रगति जानकारी POSIX उपयोगिता द्वारा मुद्रित नहीं की जानी चाहिए


मैं इसे प्रत्येक POSIX उपयोगिता के विनिर्देशों में दिए गए "STDERR" खंड के अर्थ का वर्णन करने के रूप में समझता हूं, मानक त्रुटि उपयोग के लिए सामान्य परिभाषा के रूप में नहीं। मुझे नहीं लगता कि टेर्डन यहाँ एक मानक पोसिक्स उपयोगिता लिख ​​रहा है; ;-)
स्टीफन किट

1
@StephenKitt न तो I. करता है, लेकिन वह अपने CTO के साथ बहस कर रहा है, जो कहता है कि stderr आउटपुट कुछ गलत होने का संकेत है, और मानक डिफ़ॉल्ट व्यवहार के रूप में उसके दावे का समर्थन करता है।
मूरू

1
यह केवल POSIX उपयोगिताओं के लिए डिफ़ॉल्ट व्यवहार के रूप में दावे का समर्थन करता है , और फिर भी केवल विशिष्ट मामलों में (उपयोगिताओं जो उल्लिखित वाक्यांश का उपयोग करता है)। POSIX का यह हिस्सा आदर्श नहीं है (AIUI), यह एक टेम्पलेट है: यह आपको बताता है कि उपयोगिता विनिर्देशों को कैसे पढ़ा जाए, यह उपयोगिताओं के व्यवहार को निर्दिष्ट नहीं करता है। विशेष रूप से, यह वाक्यांशों के अर्थ को परिभाषित करता है "मानक त्रुटि का उपयोग केवल नैदानिक ​​संदेशों के लिए किया जाएगा।" और "इस्तेमाल नहीं किया।" उपयोगिता विनिर्देशों के "STDERR" वर्गों में। प्रत्येक उपयोगिता इसके व्यवहार को निर्दिष्ट करती है, और यह उन वाक्यांशों का उपयोग शॉर्टहैंड के रूप में कर सकती है।
स्टीफन किट

@StephenKitt जो मेरी बात नहीं बदलता। POSIX उपयोगिताओं या तो a) stderr के लिए आउटपुट नहीं है, b) इसका उपयोग केवल नैदानिक ​​संदेशों के लिए करते हैं यदि कुछ गलत होता है, c) इसका उपयोग केवल नैदानिक ​​संदेशों के लिए करते हैं भले ही कुछ भी गलत न हो और d) किसी और चीज़ के लिए इसका उपयोग करें। मैंने कहा कि वे इसका उपयोग केवल नैदानिक ​​संदेशों के लिए करते हैं यदि कुछ गलत हो जाता है (ए, बी), जब तक कि अन्यथा (सी, डी) नहीं कहा जाता है। अब, मेरा दावा है कि यह डिफ़ॉल्ट है, जो यह स्पष्ट रूप से है, इसलिए यह टेम्पलेट है।
मूरू

2
ठीक है, मैं कहूंगा कि "जब तक अन्यथा निर्दिष्ट नहीं किया जाता है" यह एक महत्वपूर्ण महत्वपूर्ण चेतावनी है: एक POSIX उपयोगिता बहुत अच्छी तरह से निर्दिष्ट कर सकती है कि यह अपनी मानक त्रुटि पर प्रगति की जानकारी को आउटपुट करती है, और यह मानकों के अनुरूप होगी। आप सही हैं, यह दिलचस्प है कि "डिफ़ॉल्ट व्यवहार" (जो अभी भी संबंधित अनुभाग में एक विशिष्ट उल्लेख की आवश्यकता है) केवल मानक त्रुटि का उपयोग करना है यदि निकास कोड भी एक त्रुटि को इंगित करता है; लेकिन यह सीमित नहीं है।
स्टीफन किट

7

अपवर्जन के सिद्धांत से, यह केवल stderr पर जा सकता है। हां, मुझे पता है कि आपने एक आधिकारिक विनिर्देश के बारे में पूछा था, जिसे मैं आपको स्टीफन किट द्वारा दिए गए POSIX विनिर्देश के लिंक से आगे प्रस्तुत नहीं कर सकता, जिसमें कहा गया है कि stderr नैदानिक ​​उद्देश्यों के लिए है।

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

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

दी, यह एक छेद छोड़ देता है - यह शायद "stdfluff" या ऐसा कुछ करना अच्छा होगा जो न तो आउटपुट के लिए है और न ही त्रुटियों लेकिन प्रगति रिपोर्ट, डिबगिंग और सोमेसुच के लिए है। वास्तव में, कुछ भी आपको ऐसा करने से रोकता है, अर्थात, आप अपनी प्रगति को फाइल करने वाले के लिए प्रिंट कर सकते हैं 3. उदाहरण:

$ perl -e 'open($fd, ">", "/dev/fd/3"); print $fd "hello\n"'

यह कोई उत्पादन नहीं करता है। (*)

$ perl -e 'open($fd, ">", "/dev/fd/3"); print $fd "hello\n"'  3>&1
hello

यह fd-3 को प्रिंट करता है, जिसे stdout पर रीडायरेक्ट किया जाता है।

(*) पहला उदाहरण कोई उत्पादन नहीं करता है लेकिन अभी भी थोड़ा दूर है; openविफल रहता है और $!होते हैं no such file or directory; बस इसे एक उदाहरण के रूप में लें, यह निश्चित रूप से बयाना में इस तरह का उपयोग करने के लिए मानसिक रूप से नहीं है। एक वास्तविक कार्यक्रम में, यदि आप इस मार्ग पर जाना चाहते हैं, तो आप परीक्षण कर सकते हैं कि क्या /dev/fd/3उपयोग करने योग्य है और इसे अपनी प्रगति रिपोर्ट को सक्रिय करने के संकेत के रूप में लें; आपको वह बहुत जल्दी करना होगा ताकि आप openवास्तविक फ़ाइलों और ऐसे ...


क्या है fd-3? तीसरी फ्लॉपी डिस्क?
पीटर मोर्टेंसन

फ़ाइल विवरणक 3, @PeterMortensen
AnoE

-1

यदि उपयोगकर्ता ने --helpगलती की है और यदि उसने कोई गलती की है तो उपयोग संदेश को रोकना चाहिए । बिना शर्त के इसे स्‍टैंडर पर प्रिंट करना अप्रिय है क्‍योंकि इसे पेजर / ग्रेप आदि के साथ देखना अधिक कठिन हो जाता है।

इसके अलावा, मैं एक तीसरा तरीका सुझा सकता हूं: प्रगति रिपोर्ट / स्पिनर / आदि के लिए खुला / देव / ट्टी।


6
क्षमा करें, लेकिन यह प्रश्न का उत्तर नहीं दे रहा है। मैंने विशेष रूप से आधिकारिक दिशानिर्देशों के लिए कहा , राय नहीं। किसी भी मामले में, भले ही मैंने राय मांगी हो, आप एक अलग सवाल का जवाब दे रहे हैं। मैं --helpसंदेशों के बारे में बात या मदद नहीं कर रहा हूँ । कृपया प्रश्न को पुनः पढ़ें।
terdon

आपने "उपयोग संदेश" का उल्लेख किया, मुझे लगा कि यह आपके द्वारा लिंक किए गए अन्य प्रश्न के शीर्षक के बजाय आपके प्रश्न का हिस्सा था। मुझे समझ में नहीं आता है कि आपको क्यों लगता है कि "आधिकारिक दिशानिर्देश" इसके लिए मौजूद हैं। उन्हें बनाने का अधिकार किसके पास होगा?
रैंडम 832

3
मुझे नहीं पता कि वे करते हैं, इसलिए मैं पूछता हूं। और आधिकारिक तौर पर, POSIX मानक में विभिन्न मिनटों के विवरण हैं कि किसी कार्यक्रम को कैसे व्यवहार किया जाना चाहिए। स्टीफन ने अपने जवाब में बताया कि स्टैडर में जाने के लिए एक अस्पष्ट सुझाव। GNU कोडिंग मानक भी कुछ इसी तरह का हो सकता है। मूल रूप से, किसी भी समूह है कि में सक्रिय है और * nix पारिस्थितिकी तंत्र के लिए कोड का उत्पादन एक मानक मैं में रुचि होगी हो सकता है।
terdon

@terdon क्या आप मौजूदा कार्यक्रमों के उदाहरणों से ठीक होंगे? कर्ल, wget और pv सभी stderr का उपयोग करते हैं, wget और pv इसे सशर्त बनाते हैं और कर्ल इसे stdout पर सशर्त बनाते हैं, जो tty नहीं है।
रैंडम 832

4
इसके अलावा, ऐसा लगता है कि आपका सीटीओ सोचता है कि एक कॉलिंग प्रोग्राम को stderr पर डेटा की मौजूदगी पर प्रतिक्रिया देनी चाहिए, क्योंकि निकास की स्थिति को देखने के बजाय एक त्रुटि हुई है। यह निश्चित रूप से बुरा अभ्यास है (और बाहर निकलने की स्थिति की जांच करने की तुलना में लिखना भी कठिन है) और उसे समझाने के लिए एक बेहतर कोण हो सकता है।
रैंडम 832
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.