OS X, bash: ओपन फाइल डिस्क्रिप्टर पर कम काम करता है, कैट नहीं


10

एक bash स्क्रिप्ट में, जिस पर मैं (Ubuntu और OS X पर चलना है) काम कर रहा हूँ, मुझे एक फाइल में सैकड़ों कमांड के आउटपुट को रीडायरेक्ट करने की आवश्यकता है। उन सभी को
जोड़ने के बजाय &>..., मैं बस करता हूं

exec 9>&1
exec 5<>/tmp/some-file.txt
exec 1>&5

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

cat /dev/fd/5

या

tee </dev/fd/5

लेकिन OS X पर, कुछ भी नहीं छपा है (और कमांड तुरंत बाहर निकलते हैं)।
हालांकि, lessमैं का उपयोग करके दोनों पर फ़ाइल की सामग्री देख सकते हैं।
मैं उपयोग करके उपरोक्त प्रभाव (दोनों OS'es पर काम करना) प्राप्त कर सकता हूं

less /dev/fd/5 | tee

लेकिन यह एक हैक की तरह लगता है।

तो, क्यों lessस्पष्ट रूप से सामान देख catसकते हैं जो ओएस एक्स पर नहीं हो सकता है? (या बीएसडी के सभी वंशज प्रभावित हैं?)
या मैं कुछ गलत कर रहा हूं?

जवाबों:


13

ओएस एक्स की तरह, सभी प्रणालियों पर जहां वे लिनक्स को छोड़कर समर्थित हैं , उद्घाटन /dev/fd/xएक करने के समान है dup(x), जिसके परिणामस्वरूप fd x फ़ाइल के समान और विशेष रूप से एक ही फ़ाइल विवरण के लिए कम या ज्यादा अंक हैं और फ़ाइल के भीतर समान ऑफसेट होगा।

लिनक्स यहां अपवाद है। लिनक्स पर, fd x पर खुलने वाली फ़ाइल के लिए /dev/fd/xएक सिम्क्लिन है /proc/self/fd/xऔर /proc/self/fd/xएक छद्म-सिमलिंक है। लिनक्स पर जब आप एक करते हैं open("/dev/fd/x", somemode), तो आपको उसी फ़ाइल पर एक नया ओपन फ़ाइल विवरण मिलता है, जिस पर ओपन होता है x। आपके द्वारा प्राप्त नया fd किसी भी तरह से fd x से संबंधित नहीं है। विशेष रूप से, ऑफसेट फ़ाइल के प्रारंभ में होगा (यदि आप इसे O_APPENDपाठ्यक्रम के साथ खोलते हैं ) और मोड (रीड / राइट / अपेंड ...) fd x पर एक से भिन्न हो सकते हैं (आप भी प्राप्त कर सकते हैं) fd x पर जो कुछ अलग है, उसे विपरीत मोड में खोलते समय पाइप के दूसरे छोर की तरह)। (इसका मतलब यह भी है कि यह उदाहरण के लिए सॉकेट्स के लिए काम नहीं करता है जिसे आप नहीं खोल सकते हैं () )।

तो, लिनक्स पर, जब आप करते हैं

exec 5<> file
echo test >&5

फ़ाइल के अंत में fd 5 की ऑफ़सेट है। यदि तुम करो

cat <&5

बाबाजी का थुल्लु।

फिर भी जब आप करते हैं:

cat /dev/fd/5

आप देखते हैं testक्योंकि fd 5 catसे fileअसंबंधित एक नया रीड-ओनली fd मिलता है ।

अन्य प्रणालियों पर, पर

cat /dev/fd/5

cat एक fd हो जाता है जो fd 5 का एक डुप्लिकेट है, इसलिए अभी भी फ़ाइल के अंत में एक ऑफसेट के साथ।

कारण है कि यह साथ काम करता है lessकि किसी कारण से, है lessएक करता है lseek()(एक है फ़ाइल की शुरुआत करने के लिए है कि एफडी पर lseek(1); lseek(0)निर्धारित करने के लिए फ़ाइल seekable है या नहीं)।

यहाँ, आप शायद पढ़ने के लिए एक fd और लेखन के लिए एक चाहते हैं यदि आप दोनों अलग अलग offsets चाहते हैं:

exec 5< file 9>&1 > file

या आपको फ़ाइल को फिर से खोलना होगा अगर अभी भी वहाँ है, या एक के lseek()रूप में lessकरता है।

ksh93और zshएक builtin के साथ ही गोले हैं lseek()ऑपरेटर हालांकि:

cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin

या:

cat /dev/fd/5 5<#((0))  # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.