यूनिक्स शेल "स्टडिन / स्टडआउट एपीआई" कितने स्थिर हैं?


20

ग्रीपिंग, जागरण, साइडिंग और पाइपिंग किसी भी यूनिक्स जैसे ऑपरेटिंग सिस्टम के उपयोगकर्ता की दिन-प्रतिदिन की दिनचर्या है, यह कमांड लाइन पर या शेल स्क्रिप्ट के अंदर हो सकता है (सामूहिक रूप से अब से फ़िल्टर कहा जाता है )।

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

वेब डेवलपमेंट बैकग्राउंड वाले किसी व्यक्ति के रूप में, मैं इस तरह के डेटा एकत्र करने और डेटा प्रोसेसिंग की तकनीकी रूप से वेब स्क्रैपिंग के साथ तुलना करता हूं - एक ऐसी तकनीक जो डेटा प्रस्तुति में थोड़ा सा बदलाव होने पर बहुत ही अस्थिर होती है।

मेरा प्रश्न अब यूनिक्स कमांड एपीआई की स्थिरता से संबंधित है।

  1. क्या यूनिक्स जैसे ऑपरेटिंग सिस्टम में कमांड उनके इनपुट और आउटपुट के संबंध में एक औपचारिक मानकीकरण का पालन करते हैं?
  2. क्या इतिहास में ऐसे उदाहरण हैं जहां कुछ महत्वपूर्ण कमांड के अद्यतन को कुछ फिल्टर की कार्यक्षमता को तोड़ने के लिए कहा गया था जो कि उक्त कमांड के पुराने संस्करण का उपयोग करके बनाया गया था?
  3. क्या यूनिक्स कमांड्स समय के साथ परिपक्व हो गए हैं कि इस तरह से बदलना बिल्कुल असंभव है कि कुछ फ़िल्टर टूट सकता है?
  4. यदि बदलती API API के कारण फ़िल्टर समय-समय पर टूट सकते हैं, तो एक डेवलपर के रूप में मैं इस समस्या से अपने फ़िल्टर की रक्षा कैसे कर सकता हूँ?

जवाबों:


17

POSIX 2008 मानक में "शेल और यूटिलिटीज" का वर्णन करने वाला एक अनुभाग है । आम तौर पर, यदि आप इस बात से चिपके रहते हैं कि संभवतः आपकी स्क्रिप्ट्स भविष्य में होने वाली प्रूफ होनी चाहिए, सिवाय संभवत: पदावनति के लिए, लेकिन वे शायद ही कभी रातोंरात होती हैं, इसलिए आपके पास अपनी स्क्रिप्ट्स को अपडेट करने के लिए बहुत समय होना चाहिए।

कुछ मामलों में जहां एकल उपयोगिता के लिए आउटपुट स्वरूप प्लेटफ़ॉर्म और संस्करणों में व्यापक रूप से भिन्न होता है, POSIX मानक में आमतौर पर कहा जाने वाला विकल्प शामिल हो सकता है -pया -Pजो एक गारंटीकृत और अनुमानित आउटपुट स्वरूप निर्दिष्ट करता है। इसका एक उदाहरण timeउपयोगिता है , जिसमें व्यापक रूप से अलग-अलग कार्यान्वयन हैं। यदि आपको एक स्थिर एपीआई / आउटपुट प्रारूप की आवश्यकता है, तो आप उपयोग करेंगे time -p

यदि आपको एक फ़िल्टर उपयोगिता का उपयोग करने की आवश्यकता है जो कि POSIX मानक द्वारा कवर नहीं है, तो आप वितरण पैकर्स / अपस्ट्रीम डेवलपर्स की दया पर वैसे ही हैं, जैसे आप वेब स्क्रैपिंग करते समय दूरस्थ वेब डेवलपर्स की दया पर हैं।


12

मैं अपने अनुभव से जवाब देने की कोशिश करूंगा।

  1. कमांड वास्तव में एक औपचारिक विनिर्देश का पालन नहीं करते हैं, लेकिन वे लाइन-ओरिएंटेड टेक्स्ट का उपभोग करने और उत्पन्न करने की आवश्यकता का पालन करते हैं।

  2. हां बिल्कुल। इससे पहले कि GNU उपयोगिताओं एक वास्तविक मानक बन गया, बहुत सारे विक्रेताओं के पास विशेष रूप से psऔर सम्मान के साथ quirky आउटपुट होगा ls। इससे बहुत दर्द हुआ। आज, केवल एचपी सुपर-क्वर्की कमांड देता है। ऐतिहासिक रूप से, बर्कले सॉफ्टवेयर वितरण (बीएसडी) उपयोगिताओं अतीत के साथ एक बड़ा ब्रेक थीं। POSIX विनिर्देश अतीत के साथ एक विराम था, लेकिन अब इसे व्यापक रूप से स्वीकार किया गया है।

  3. यूनिक्स कमांड वास्तव में समय के साथ परिपक्व हो गए हैं। पुराने संस्करण के लिए लिखी गई कुछ स्क्रिप्ट को तोड़ना अभी भी असंभव नहीं है। टेक्स्ट फ़ाइल एन्कोडिंग के रूप में UTF-8 की ओर हाल के रुझान के बारे में सोचें। इस परिवर्तन की तरह मूलभूत उपयोगिताओं में परिवर्तन की आवश्यकता है tr। अतीत में, सरल पाठ लगभग हमेशा ASCII (या कुछ करीब) था, इसलिए अपरकेस अक्षरों ने एक संख्यात्मक श्रेणी बनाई, जैसा कि लोअरकेस अक्षर थे। यह अब UTF-8 के साथ सच नहीं है, इसलिए tr"अपरकेस" या "अल्फ़ान्यूमेरिक" जैसी चीज़ों को निर्दिष्ट करने के लिए अलग-अलग कमांड लाइन विकल्पों को स्वीकार करता है।

  4. आपके फ़िल्टर को "बीहड़" करने के सर्वोत्तम तरीकों में से एक विशेष टेक्स्ट लेआउट पर निर्भर नहीं करना है। उदाहरण के लिए, मत करो cut -c10-24, जो एक पंक्ति के पदों पर निर्भर करता है। cut -f2इसके बजाय का उपयोग करें , जो 2, टैब से अलग फ़ील्ड को काट देगा। awkकिसी भी इनपुट लाइन को $ 1, $ 2, $ 3 में तोड़ देता है ... जो कि श्वेत-स्थान डिफ़ॉल्ट रूप से अलग हो जाते हैं। स्तंभ स्थिति जैसी निम्न-स्तरीय अवधारणाओं के बजाय "फ़ील्ड" जैसी उच्च-स्तरीय अवधारणाओं पर निर्भर करें। इसके अलावा, नियमित अभिव्यक्तियों का उपयोग करें: sedऔर awkदोनों नियमित अभिव्यक्ति के साथ चीजें कर सकते हैं जो इनपुट में कुछ विचरण के बारे में परवाह नहीं करते हैं। एक और तरकीब है इनपुट को कुछ ऐसी प्रक्रिया में डालना जिसके प्रारूप को आपके फ़िल्टर के बारे में चुना जा सके। tr -cs '[a-zA-z0-9]' '[\n]'विराम चिह्न के बिना, प्रति पंक्ति एक शब्द में पाठ को तोड़ने के लिए उपयोग करें । आप सिर्फ डॉन


9

सबसे पहले, आपके सवालों के बहुत ही संक्षिप्त उत्तर:

  1. इनपुट / आउटपुट सम्मेलनों का औपचारिक मानकीकरण: नहीं
  2. बदलते आउटपुट के कारण अतीत में टूटना: हाँ
  3. भविष्य के फिल्टर को तोड़ने के लिए बिल्कुल असंभव है: नहीं
  4. मैं खुद को परिवर्तनों से कैसे बचा सकता हूं: रूढ़िवादी हो

जब आप "एपीआई" कहते हैं, तो आप एक शब्द का उपयोग कर रहे हैं (अच्छे या बीमार के लिए) फ़िल्टर इनपुट / आउटपुट सम्मेलनों के आसपास बहुत अधिक औपचारिकता। बहुत (और मेरा मतलब है "बहुत") मोटे तौर पर, डेटा के लिए प्राथमिक कन्वेंशन जो आसान फ़िल्टरिंग के लिए सक्षम हैं

  • प्रत्येक इनपुट लाइन एक पूरा रिकॉर्ड है
  • प्रत्येक रिकॉर्ड के भीतर, खेतों को एक ज्ञात सीमांकक चरित्र द्वारा अलग किया जाता है

एक क्लासिक उदाहरण / etc / passwd का प्रारूप होगा। लेकिन, इन डिफ़ॉल्ट सम्मेलनों का शायद कुछ हद तक उल्लंघन किया जाता है जितना कि वे पत्र का अनुसरण करते हैं।

  • बहुत सारे फ़िल्टर हैं (अक्सर awk या perl में लिखे गए हैं) जो मल्टीलाइन इनपुट फॉर्मेट को पार्स करते हैं।
  • बहुत सारे इनपुट पैटर्न हैं (उदाहरण के लिए, / var / log / संदेश) जहां कोई अच्छी तरह से परिभाषित क्षेत्र संरचना नहीं है, और अधिक सामान्य नियमित अभिव्यक्ति-आधारित तकनीकों का उपयोग किया जाना चाहिए।

आपका चौथा सवाल, आउटपुट संरचना में बदलाव के खिलाफ खुद को कैसे सुरक्षित रखें, वास्तव में केवल एक ही है जिसके बारे में आप कुछ भी कर सकते हैं।

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

अंत में, आप अपने आप को उन समस्याओं से पूरी तरह से सुरक्षित नहीं रख सकते हैं जिनके बारे में आप चिंतित हैं, और एक निश्चित कमांड क्या करना चाहिए के "निश्चित" बयान के लिए देखने के लिए कोई एकल स्थान नहीं है। कई शेल स्क्रिप्ट के लिए, विशेष रूप से व्यक्तिगत या छोटे पैमाने पर उपयोग के लिए लिखे गए, यह केवल एक समस्या नहीं है


5

केवल 1) आपके प्रश्न का कवर।

स्वाभाविक रूप से एपीआई हमेशा अपने रचनाकारों की इच्छा पर बदल सकते हैं, और इस तरह किसी भी भाषा में निर्भर सॉफ्टवेयर को तोड़ सकते हैं। उस ने कहा, यूनिक्स उपकरण ' I / O "APIs का महान विचार यह है कि व्यावहारिक रूप से कोई भी नहीं है (शायद 0x0aपंक्ति के अंत के रूप में)। एक अच्छी स्क्रिप्ट डेटा को बनाने के बजाय यूनिक्स टूल्स के साथ फ़िल्टर करती है। इसका मतलब है कि आपकी स्क्रिप्ट टूट सकती है क्योंकि इनपुट या आउटपुट कल्पना बदल गई है, लेकिन इसलिए नहीं कि स्क्रिप्ट में उपयोग किए गए अलग-अलग टूल के I / O प्रारूप (फिर से, वास्तव में एक नहीं है) (क्योंकि कुछ ऐसा है जो वास्तव में मौजूद नहीं है) वास्तव में बदल नहीं सकते)।

बुनियादी उपकरणों की एक सूची के माध्यम से जा रहे हैं, वहाँ कुछ है कि मैं भी निर्माता विशेषता होगी , केवल फिल्टर के विपरीत:

  • wc - बाइट्स, शब्द, रेखाओं की प्रिंट संख्या - बहुत सरल प्रारूप, इस प्रकार परिवर्तन की पूरी संभावना नहीं है, और इसके अलावा एक स्क्रिप्ट में उपयोग किए जाने की बहुत संभावना नहीं है।
  • अंतर - अलग-अलग आउटपुट स्वरूप विकसित हुए हैं, लेकिन मैंने किसी भी समस्या के बारे में नहीं सुना है। पर्यवेक्षण के बिना भी सामान्य रूप से उपयोग नहीं किया जाता है।
  • दिनांक - अब यहाँ हमें वास्तव में ध्यान रखना है कि हम क्या उत्पादन करते हैं, खासकर सिस्टम लोकेल के बारे में। लेकिन अन्यथा आउटपुट फॉर्मेट RFC'ed दिया जाता है, आप इसे स्वयं निर्दिष्ट नहीं करते हैं।
  • cal - चलो इसके बारे में बात नहीं करते हैं, मुझे पता है कि आउटपुट प्रारूप पूरे सिस्टम में बहुत भिन्न होता है।
  • ls , जो , w , last - यदि आप ls को पार्स करना चाहते हैं तो मैं मदद नहीं कर सकता, यह सिर्फ होना ही नहीं था। इसके अलावा, कौन, w, अंतिम, अधिक संवादात्मक श्रोता हैं; यदि आप उन्हें एक स्क्रिप्ट में उपयोग करते हैं तो आपको ध्यान रखना होगा कि आप क्या करते हैं।
  • समय एक और पोस्ट में बताया गया था। लेकिन हाँ, यह ls के समान है। इंटरैक्टिव / स्थानीय उपयोग के लिए अधिक। और बाश बिलिन जीएनयू संस्करण से बहुत अलग है, और जीएनयू संस्करण में कई वर्षों तक बग़ैर कीड़े हैं। बस इस पर भरोसा मत करो।

यहां ऐसे उपकरण हैं जो किसी विशेष इनपुट प्रारूप को बाइट स्ट्रीम से अधिक विशिष्ट होने की उम्मीद करते हैं:

  • बीसी , डीसी - कैलकुलेटर। पहले से ही चीजों के अधिक हैकिश पक्ष पर (वास्तव में, मैं उन्हें स्क्रिप्ट में उपयोग नहीं करता हूं), और संभवतः बहुत स्थिर I / O प्रारूप।

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

  • रेगेक्स - रेगेक्स का उपयोग करने वाले सभी उपकरण सिस्टम लोकेल (उदाहरण LC_COLLATE) के आधार पर अर्थ बदल सकते हैं और रेगेक्स कार्यान्वयन में कई सूक्ष्मताएं और विशिष्टताएं हैं।
  • बस फैंसी स्विच का उपयोग न करें। आप man 1p findउदाहरण के लिए आसानी से उपयोग कर सकते हैं , सिस्टम मैनपेज के बजाय पोसिक्स फाइंड मैनपेज पढ़ने के लिए। मेरे सिस्टम पर, मुझे मैनपेज़-पॉज़िक्स स्थापित करने की आवश्यकता है।

और इस तरह के स्विच का उपयोग करते समय भी, आम तौर पर त्रुटियों को सूक्ष्मता से पेश नहीं किया जाएगा और आपके डेटा को जहर कर देगा। अधिकांश कार्यक्रम बस एक अज्ञात स्विच के साथ काम करने से मना कर देंगे।

समाप्त करने के लिए, मैं कहूंगा कि शेल में वास्तव में सबसे अधिक पोर्टेबल भाषाओं में से एक होने की क्षमता है (यह पोर्टेबल है जब आप स्क्रिप्टिंग करते हैं)। अपनी पसंदीदा स्क्रिप्टिंग भाषाओं की तुलना करें जहां सूक्ष्म त्रुटियां होती हैं, या आपका पसंदीदा संकलित कार्यक्रम जो संकलन करने के लिए बंद हो जाएगा।

इसके अतिरिक्त, दुर्लभ स्थानों पर जहां असंगति के कारण टूट-फूट हो सकती है, यह शायद समय से प्रेरित होने के कारण नहीं होगा, लेकिन विभिन्न प्रणालियों में विविधता के कारण (इसका मतलब है कि अगर यह आपके लिए काम करता है, तो यह 20 साल पहले और 20 वर्षों में ऐसा किया था। , भी)। यह उपकरण की सादगी का एक पुंज है।


1

केवल वास्तविक फैक्टर IO मानक हैं - व्हॉट्सएप और अशक्त अलग आउटपुट।

अनुकूलता के लिए, हम आमतौर पर अलग-अलग फ़िल्टर के संस्करण संख्याओं की जाँच करते हैं। ऐसा नहीं है कि वे बहुत बदल जाते हैं, लेकिन जब आप एक नई सुविधा का उपयोग करना चाहते हैं और फिर भी स्क्रिप्ट को पुराने संस्करणों पर चलाना चाहते हैं, तो आपको इसे किसी भी तरह "ifdef" करना होगा। व्यावहारिक रूप से कोई क्षमता रिपोर्टिंग तंत्र नहीं है, मैन्युअल रूप से परीक्षण मामलों को लिखने के लिए सहेजें।


0

लिपियाँ टूटती हैं, दूसरों की तुलना में कुछ अधिक बार। पुराने और प्रसिद्ध सॉफ्टवेयर अपेक्षाकृत समान रहते हैं, और जब भी यह बदलता है तो अक्सर संगतता झंडे होते हैं।

एक प्रणाली पर लिखी गई लिपियों से काम चल जाता है, लेकिन अक्सर दूसरा टूट जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.