क्यों `सॉर्ट <(ls -l)` काम करता है, लेकिन `सॉर्ट <(ls -l)` फेल?


32

आज मैं इस लेख के साथ फीफो के बारे में कुछ सीख रहा हूं: नामांकित पाइप्स का परिचय , जिसमें उल्लेख है cat <(ls -l)

मैंने प्रयोग करके कुछ प्रयोग किए sort < (ls -l), जो एक त्रुटि उत्पन्न करता है:

-bash: syntax error near unexpected token `('`

फिर मैंने पाया कि मैंने कमांड में एक अतिरिक्त जगह को गुमराह किया है।

लेकिन, यह अतिरिक्त आदेश इस विफलता का कारण क्यों बनेगा? पुनर्निर्देशन प्रतीक के करीब क्यों होना चाहिए (?


यह ध्यान दिया जाना चाहिए कि * निक्स के गोले व्हाट्सएप के आधार पर चीजों को विभाजित करते हैं जो एलेक द्वारा उल्लिखित टोकन बनाता है।
चूजों

जवाबों:


45

क्योंकि यह एक नहीं है <, यह एक है <()जो पूरी तरह से अलग है। इसे प्रक्रिया प्रतिस्थापन कहा जाता है , यह कुछ विशिष्ट गोले की एक विशेषता है जो आपको एक प्रक्रिया के आउटपुट को दूसरे के लिए इनपुट के रूप में उपयोग करने की अनुमति देता है।

>और <ऑपरेटरों से करने के लिए उत्पादन और इनपुट अनुप्रेषित फ़ाइलें<()ऑपरेटर आदेशों (प्रक्रियाओं) के साथ संबंधित, नहीं फ़ाइलें। जब तुम दौड़ते हो

sort < (ls)

आप कमांड lsको सबशेल में चलाने का प्रयास कर रहे हैं (जो कि कोष्ठक का अर्थ है), फिर इनपुट फ़ाइल के रूप में उस उपधारा को पास करना sort। यह, हालांकि, वाक्यविन्यास स्वीकार नहीं किया जाता है और आपको वह त्रुटि मिलती है जिसे आपने देखा था।


3
आपका उत्तर अच्छा है, लेकिन then sort is attempting to read the subshell as its input file→ यह स्पष्ट रूप से गलत है, क्योंकि बैश भी सिंटैक्स को पार्स नहीं करेगा। न तो lsहै और न ही sortवास्तव में चलाया जाता है।
18 मई को स्लब्लैक

1
@sebleblanc उचित बिंदु, जवाब rephrased, धन्यवाद।
terdon

1
इस मामले में कोई उप-शेल नहीं है। < (ls)यहां वैध टोकन नहीं है।
congonglm

@ cuonglm no, क्योंकि bash इसे सिंटैक्स त्रुटि के रूप में मानता है। मेरा कहना है कि एक उपधारा में (ls)चलेगा ls
terdon

22

क्योंकि ऐसा ही होना है।

<(...)में bashप्रक्रिया प्रतिस्थापन के लिए वाक्य रचना है। यह उसी ऑपरेटर से कॉपी किया गया है ksh

<, (, ), |, &, ;विशेष शाब्दिक टोकन में हैं bashकि विभिन्न संयोजनों में विशेष ऑपरेटरों के रूप में उपयोग किया जाता है। <, <(, <<, <&... प्रत्येक उनकी भूमिका की है। <पुनर्निर्देशन के लिए है। <file, < fileएक फ़ाइल से इनपुट को पुनर्निर्देशित करेगा। <'(file)'नामक फ़ाइल से इनपुट पुनर्निर्देशित करेगा (file), लेकिन <(file)एक अलग ऑपरेटर है जो पुनर्निर्देशन ऑपरेटर नहीं है।

< (file)इसके <बाद होगा (file)। उस संदर्भ में, में bash, (file)मान्य नहीं है। (...)कुछ संदर्भों में एकल टोकन के रूप में मान्य किया जा सकता है:

(sub shell)
func () {
  ...
}
var=(foo bar)

लेकिन में नहीं

sort < (cmd)

में fishखोल, यह अलग है। में fish, (...)आदेश प्रतिस्थापन (के बराबर के लिए है $(...)में bash)। और <बॉर्न जैसे गोले में इनपुट पुनर्निर्देशन के लिए है।

तो में fish:

sort <(echo file)

जैसा होगा:

sort < (echo file)

अर्थात्:

sort < file

लेकिन यह कुछ bashप्रक्रिया प्रतिस्थापन से पूरी तरह से अलग है ।

में yashखोल, एक और POSIX खोल, <(...)के लिए नहीं है प्रक्रिया प्रतिस्थापन लेकिन के लिए प्रक्रिया पुनर्निर्देशन

वहाँ पर,

sort <(ls -l)

के लिए कम:

sort 0<(ls -l)

एक पुनर्निर्देशन ऑपरेटर है। यह कम या ज्यादा के बराबर है:

ls -l | sort

जबकि bash, <(ls -l)एक पाइप के मार्ग में विस्तारित है, इसलिए यह अधिक पसंद है:

ls -l | sort /dev/fd/0

में zsh, (...)एक ग्लोबिंग ऑपरेटर के रूप में ओवरलोड किया गया है ( और फ़ाइलों का (*.txt|*.png)विस्तार होगा ) और ग्लोब क्वालिफायर के रूप में ( उदाहरण के लिए निर्देशिका फ़ाइलों का विस्तार होता है)।txtpng*(/)

में zsh, में:

sort < (ls -l)

यही कारण है कि (ls -l)एक ग्लोब क्वालीफायर के रूप में माना जाएगा। lग्लोब लिंक्स की संख्या पर मैच के लिए है और के बाद एक नंबर की उम्मीद क्वालीफायर l(के रूप में ls -ld ./*(l2)2 लिंक के साथ फ़ाइलों की सूची है), तो यह है कि के कारण है कि आप एक मिल zsh: number expectedत्रुटि।

sort < (w)zsh: no matches found: (w)इसके बजाय एक त्रुटि दी गई होगी जो (w)खाली नाम वाली फाइलों से मेल खाती है जो कि लेखन योग्य हैं।

sort < (w|cat)वर्तमान निर्देशिका में wऔर / या catफ़ाइलों की सामग्री को सॉर्ट किया गया होता ...


sort < $(ls -l)यह त्रुटि क्यों देता है:bash: $(ls -l): ambiguous redirect
एडवर्ड टॉर्वाड्स

@edwardtorvalds, क्योंकि $(ls -l)एक से अधिक शब्दों तक फैलता है। विभाजन + ग्लोब ( sort < "$(echo file)") को रोकने के लिए उद्धरणों का उपयोग करें । ध्यान दें कि bashउस बैश में POSIX श से व्यवहार या भिन्नता उस विभाजन + ग्लोब को वहां तब करती है जब गैर-संवादात्मक (जब कहा जाता है तब नहीं sh)।
स्टीफन चेज़लस

ls -l | sort /dev/fd/0मैं देख कर कह सकता हूं कि इसमें आउटपुट का ls -lसंग्रह है /dev/fd/0और sortकमांड वांछित आउटपुट देने के लिए इसे पढ़ता है। मैं tail -f --retry /dev/fd/0उस फ़ाइल की निगरानी करने के लिए उपयोग कर रहा हूं लेकिन मुझे कोई आउटपुट नहीं मिल रहा है। क्यूं कर? मैं उस फ़ाइल को कैसे पढ़ सकता हूँ?
एडवर्ड टॉर्वाल्ड्स

मछली में, आप (foo | psub)इनपुट प्रक्रिया प्रतिस्थापन प्राप्त करने के लिए उपयोग कर सकते हैं ; आउटपुट प्रक्रिया प्रतिस्थापन के लिए कोई विकल्प (हा) नहीं है।
ज़ेंकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.