3>&4-
kash93 एक्सटेंशन को भी bash द्वारा सपोर्ट किया गया है और जो 3>&4 4>&-
कि 3 के लिए छोटा है , जो कि 4 के लिए इस्तेमाल किया जाता है, और 4 अब बंद हो गया है, इसलिए 4 से जो इंगित किया गया था, वह अब 3 हो गया है।
विशिष्ट उपयोग उन मामलों में होगा जहां आपने डुप्लिकेट किया है stdin
या इसकी stdout
एक प्रति सहेजना चाहते हैं और इसे पुनर्स्थापित करना चाहते हैं, जैसे:
मान लें कि आप एक चर में stdout को छोड़ते समय कमांड (और केवल stderr) का स्टैडर पकड़ना चाहते हैं।
कमांड प्रतिस्थापन var=$(cmd)
, एक पाइप बनाता है। पाइप का राइटिंग एंड cmd
स्टडआउट (फाइल डिस्क्रिप्टर 1) बन जाता है और दूसरे सिरे को वेरिएबल को भरने के लिए शेल द्वारा पढ़ा जाता है।
अब, यदि आप stderr
चर पर जाना चाहते हैं, तो आप ऐसा कर सकते हैं var=$(cmd 2>&1)
:। अब दोनों fd 1 (stdout) और 2 (stderr) पाइप पर जाते हैं (और अंत में चर), जो हम चाहते हैं उसका केवल आधा है।
यदि हम करते हैं var=$(cmd 2>&1-)
(छोटा है var=$(cmd 2>&1 >&-
), तो अब केवल cmd
स्टडर पाइप में जाता है, लेकिन fd 1 बंद है। यदि cmd
कोई आउटपुट लिखने की कोशिश करता है EBADF
, तो वह एक त्रुटि के साथ लौटेगा , यदि वह एक फाइल खोलता है, तो उसे पहली फ्री एफडी मिलेगी और ओपन फाइल को stdout
तब तक सौंपा जाएगा जब तक कि कमांड गार्ड उसके खिलाफ नहीं हो जाता! वह नहीं जो हम चाहते हैं।
यदि हम चाहते हैं कि स्टैडआउट को cmd
अकेला छोड़ दिया जाए, तो यह उसी संसाधन की ओर इशारा करता है, जो उसने कमांड प्रतिस्थापन के बाहर की ओर इशारा किया है, तो हमें किसी तरह से उस संसाधन को कमांड प्रतिस्थापन के अंदर लाने की आवश्यकता है। उसके लिए हम कमांड प्रतिस्थापन के stdout
बाहर की एक प्रति अंदर ले जा सकते हैं।
{
var=$(cmd)
} 3>&1
जो लिखने के लिए एक साफ तरीका है:
exec 3>&1
var=$(cmd)
exec 3>&-
(जो अंत में बंद करने के बजाय fd 3 को पुनर्स्थापित करने का लाभ है)।
फिर {
(या exec 3>&1
) और अप करने के लिए }
, दोनों fd 1 और 3 एक ही संसाधन के लिए इंगित करें fd 1 शुरू में बताया। fd 3 कमांड प्रतिस्थापन के अंदर उस संसाधन को भी इंगित करेगा (कमांड प्रतिस्थापन केवल fd 1, stdout को पुनर्निर्देशित करता है)। तो ऊपर, के लिए cmd
, हम 1, 2, 3 के लिए मिल गया है:
- var के लिए पाइप
- अछूता
- कमांड प्रतिस्थापन के बाहर 1 अंक के समान
यदि हम इसे बदल देते हैं:
{
var=$(cmd 2>&1 >&3)
} 3>&1-
फिर यह बन जाता है:
- कमांड प्रतिस्थापन के बाहर 1 अंक के समान
- var के लिए पाइप
- कमांड प्रतिस्थापन के बाहर 1 अंक के समान
अब, हमें वह मिल गया है जो हम चाहते थे: स्टादर पाइप में जाता है और स्टडआउट को अछूता छोड़ दिया जाता है। हालाँकि, हम उस fd 3 को लीक कर रहे हैं cmd
।
जबकि कमांड (कन्वेंशन द्वारा) एफडीएस को 0 से 2 के लिए खुला माना जाता है और मानक इनपुट, आउटपुट और त्रुटि हो, वे अन्य एफडी के कुछ भी ग्रहण नहीं करते हैं। सबसे अधिक संभावना है कि वे उस fd 3 को अछूता छोड़ देंगे। यदि उन्हें किसी अन्य फ़ाइल डिस्क्रिप्टर की आवश्यकता होती है, तो वे बस वही करेंगे open()/dup()/socket()...
जो पहले उपलब्ध फ़ाइल डिस्क्रिप्टर को वापस कर देगा। यदि (एक शेल स्क्रिप्ट की तरह exec 3>&1
) जो उन्हें fd
विशेष रूप से उपयोग करने की आवश्यकता है , तो वे पहले इसे कुछ को असाइन करेंगे (और उस प्रक्रिया में, हमारे fd 3 द्वारा आयोजित संसाधन को उस प्रक्रिया द्वारा जारी किया जाएगा)।
यह अच्छा है कि fd 3 को बंद करें क्योंकि cmd
इसका उपयोग नहीं किया जाता है, लेकिन यदि हम कॉल करने से पहले इसे छोड़ देते हैं तो यह कोई बड़ी बात नहीं है cmd
। समस्याएं हो सकती हैं: cmd
(और संभावित रूप से अन्य प्रक्रियाएं जो इसे पैदा करती हैं) इसमें एक कम एफडी उपलब्ध है। संभावित रूप से अधिक गंभीर समस्या यह है कि यदि संसाधन कि fd अंक cmd
पृष्ठभूमि में उसके द्वारा प्रायोजित प्रक्रिया द्वारा आयोजित किया जा सकता है । यह एक चिंता का विषय हो सकता है यदि वह संसाधन एक पाइप या अन्य अंतर-प्रक्रिया संचार चैनल है (जैसे कि जब आपकी स्क्रिप्ट के रूप में चलाया जा रहा है script_output=$(your-script)
), इसका मतलब है कि दूसरे छोर से पढ़ने की प्रक्रिया कभी भी अंत-फ़ाइल को तब तक नहीं दिखाई देगी जब तक कि पृष्ठभूमि की प्रक्रिया समाप्त हो जाती है।
इसलिए यहां लिखना बेहतर है:
{
var=$(cmd 2>&1 >&3 3>&-)
} 3>&1
जिसे bash
छोटा किया जा सकता है:
{
var=$(cmd 2>&1 >&3-)
} 3>&1
कारणों का योग करने के लिए कि इसका उपयोग शायद ही कभी क्यों किया जाता है:
- यह अमानक है और बस वाक्यविन्यास चीनी है। आपको अपनी स्क्रिप्ट को कम पोर्टेबल बनाने के साथ कुछ कीस्ट्रोक्स को बचाने के लिए संतुलन मिला है और लोगों को उस असामान्य सुविधा का उपयोग नहीं करने के लिए कम स्पष्ट है।
- यह डुप्लिकेट करने के बाद मूल fd बंद करने के लिए की जरूरत अक्सर अनदेखी की है, क्योंकि समय के सबसे अधिक है, हम परिणाम से है, तो हम बस करो ग्रस्त नहीं है
>&3
बजाय >&3-
या >&3 3>&-
।
सबूत है कि यह शायद ही कभी इस्तेमाल किया जाता है, जैसा कि आपको पता चला है कि यह बाश में फर्जी है । बैश compound-command 3>&4-
या any-builtin 3>&4-
पत्तियों में fd 4 बंद होने के बाद भी compound-command
या any-builtin
वापस आ गया है। समस्या को ठीक करने के लिए एक पैच अब (2013-02-19) उपलब्ध है।