Zsh में, बिल्ली के बीच अंतर <(cat) बनाम बिल्ली | बिल्ली बनाम बिल्ली = (बिल्ली)?


18

मुझे उम्मीद थी cat <(cat)और cat | catएक ही काम करने के लिए: स्टड से स्टडआउट तक लाइनों को कॉपी करें। मेरी समझ यह थी कि दोनों catएक सब-सब्मिट में अंजाम देंगे , सब-स्टैडआउट catको एक अस्थायी नाम वाले पाइप पर पुनर्निर्देशित करें , और फिर catमौजूदा शेल में दूसरे को निष्पादित करें, जिसके स्टड को पाइप पर पुनर्निर्देशित किया गया है।

इसके बजाय, cat <(cat)मुझे अपने टर्मिनल पर टाइप करने देता है, लेकिन इनपुट लाइनों में से कोई भी नकल नहीं करता है और ^Dसंकेत करने में विफल रहता है EOF; cat | catउम्मीद के मुताबिक काम करता है।

एक और प्रयोग के रूप में, मैंने जाँच की कि cat =(cat)क्या ऐसी ही कठिनाइयाँ हैं cat <(cat), लेकिन यह मेरी अपेक्षा के अनुरूप काम करती है: सभी एक समय ^Dमें एक नकल करने के लिए नकल हो जाती है।

क्या कोई मुझे समझने में मदद कर सकता है कि हुड के नीचे क्या है?

जवाबों:


23
  1. a | bजोड़ता STDOUTसे aऔर STDINसे bका उपयोग करके बस dup/dup2। दोनों आदेशों को समानांतर में निष्पादित किया जाता है।

  2. a =(b)aअस्थायी फ़ाइल नाम के साथ तर्क को प्रतिस्थापित करता है । bइससे पहले aकि अस्थायी फ़ाइल बनाने से पहले इसे पारित किया जा सकता है के रूप में निष्पादित किया जाना चाहिएa

  3. a <(b)aनामित पाइप के साथ तर्क को प्रतिस्थापित करता है । aऔर bसमानांतर में चलते हैं। यह अब है जहाँ यह थोड़ा जटिल हो जाता है:

    bपृष्ठभूमि में है और टर्मिनल से नहीं पढ़ सकता है। आप strace -p $PIDप्रक्रिया को देखने के लिए अपनी दूसरी बिल्ली की प्रक्रिया में संलग्न करके इसका स्वयं परीक्षण कर सकते हैं।

    aइस बीच नामित पाइप से पढ़ने की कोशिश करता है, लेकिन कुछ भी नहीं पढ़ सकता है जैसा कि bपढ़ नहीं सकता है।

    • इसका मतलब है कि आपके पास मूल रूप से एक गतिरोध है जहां aसे पढ़ने की कोशिश करता है, bलेकिन इससे bनहीं पढ़ सकता है STDINऔर लिख नहीं सकता हैa

मैन बैश से बैकग्राउंड प्रोसेस और टर्मिनल के बारे में अधिक जानकारी :

उपयोगकर्ता इंटरफ़ेस को नौकरी पर नियंत्रण के कार्यान्वयन की सुविधा के लिए, ऑपरेटिंग सिस्टम एक वर्तमान टर्मिनल प्रक्रिया समूह आईडी की धारणा को बनाए रखता है । इस प्रक्रिया समूह के सदस्य (ऐसी प्रक्रियाएँ जिनकी प्रक्रिया समूह आईडी वर्तमान टर्मिनल प्रक्रिया समूह आईडी के बराबर है) कीबोर्ड-जनित संकेत प्राप्त करती है जैसे कि SIGINT । इन प्रक्रियाओं को अग्रभूमि में कहा जाता है । पृष्ठभूमिप्रक्रियाएं वे हैं जिनकी प्रक्रिया समूह आईडी टर्मिनल से अलग है; इस तरह की प्रक्रियाएं कीबोर्ड से उत्पन्न संकेतों के लिए प्रतिरक्षा हैं। केवल अग्रभूमि प्रक्रियाओं को पढ़ने की अनुमति दी जाती है या, यदि उपयोगकर्ता बहुत ही स्टॉप टॉपटॉप के साथ निर्दिष्ट करता है, तो टर्मिनल को लिखें। पृष्ठभूमि की प्रक्रियाएं जो पढ़ने की कोशिश करती हैं (लिखने के लिए जब स्टॉप टॉपटॉप प्रभाव में है) टर्मिनल को कर्नेल के टर्मिनल ड्राइवर द्वारा एक SIGTTIN (SIGTTOU) सिग्नल भेजा जाता है, जो कि पकड़े जाने तक, प्रक्रिया को निलंबित कर देता है।


महान, धन्यवाद - यह बहुत कुछ साफ कर दिया!
एलन ओ'डॉनेल

1
ध्यान दें कि जब इंटरेक्टिव नहीं है, तो zsh बैकग्राउंड कमांड्स के स्टैंडर्ड इनपुट (जिसमें वे भी शामिल हैं <(cmd)) को रीडायरेक्ट करता है /dev/null, इसलिए व्यवहार अलग-अलग होता है ( zsh -c 'cat <(cat)'तुरंत कुछ भी आउटपुट नहीं करता है)।
स्टीफन चेज़ेलस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.