मुझे नहीं लगता कि यह पूरी तरह से एक बैश मुद्दा है।
एक टिप्पणी में, आपने कहा कि आपने यह त्रुटि देखी थी
sudo su username2
जब में लॉग इन किया username
। यह su
समस्या को ट्रिगर कर रहा है।
/dev/stdout
एक सहिष्णु है /proc/self/fd/1
, जो उदाहरण के लिए, के लिए एक सहानुभूति है /dev/pts/1
। /dev/pts/1
, जो एक छद्म शब्द है, जिसका स्वामित्व है, और इसके द्वारा लिखित है username
; username
जब आप लॉग इन करते हैं तो वह स्वामित्व प्रदान किया गया था। जब आप sudo su username2
का स्वामित्व /dev/pts/1
नहीं बदलता है, और username2
लिखित अनुमति नहीं होती है।
मेरा तर्क है कि यह एक बग है। वास्तव में, मानक आउटपुट स्ट्रीम के लिए एक उपनाम /dev/stdout
होना चाहिए , लेकिन यहां हम ऐसी स्थिति देखते हैं जहां echo hello
काम करता है लेकिन echo hello > /dev/stdout
विफल रहता है।
एक वर्कअराउंड username2
समूह का सदस्य बनाना होगा tty
, लेकिन यह किसी भी tty username2
को लिखने की अनुमति देगा , जो संभवतः अवांछनीय है।
username2
उपयोग करने के बजाय खाते में प्रवेश करने के लिए एक और समाधान होगा su
, ताकि /dev/stdout
एक नए आवंटित किए गए छद्म सुव्यवस्थित स्वामित्व की ओर इशारा किया जाए username2
। यह व्यावहारिक नहीं हो सकता है।
एक और वर्कअराउंड आपकी स्क्रिप्ट्स को संशोधित करना होगा ताकि वे इसका उल्लेख न करें /dev/stdout
और /dev/stderr
; उदाहरण के लिए, इसे प्रतिस्थापित करें:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
इसके द्वारा:
echo OUT
echo ERR 1>&2
मैं इसे अपने स्वयं के सिस्टम, Ubuntu 12.04 पर, बैश 4.2.24 के साथ देखता हूं - भले ही info bash
मेरे सिस्टम पर बैश दस्तावेज़ ( ) कहता है कि /dev/stdout
और /dev/stderr
रीडायरेक्शन में उपयोग किए जाने पर विशेष रूप से व्यवहार किया जाता है। लेकिन अगर बैश उन नामों को विशेष रूप से व्यवहार नहीं करता है, तो भी उन्हें मानक I / O धाराओं के समकक्ष कार्य करना चाहिए। (POSIX उल्लेख नहीं करता है /dev/std{in,out,err}
, इसलिए यह तर्क देना मुश्किल हो सकता है कि यह एक बग है।)
बैश के पुराने संस्करणों को देखते हुए, प्रलेखन का अर्थ है कि /dev/stdout
एट अल को विशेष रूप से माना जाता है कि फाइलें मौजूद हैं या नहीं। फीचर को bash 2.04 में पेश किया गया था, और NEWS
उस संस्करण की फ़ाइल कहती है:
पुनर्निर्देशन कोड अब कई फाइलनामों को विशेष रूप से संभालता है: / dev / fd / N, / dev / stdin, / dev / stdout, और / dev / stderr, चाहे वे फ़ाइल सिस्टम में मौजूद हों या नहीं।
लेकिन यदि आप स्रोत कोड ( redir.c
) की जांच करते हैं , तो आप देखेंगे कि विशेष हैंडलिंग केवल तभी सक्षम है जब प्रतीक HAVE_DEV_STDIN
परिभाषित किया गया है (यह निर्धारित किया जाता है कि जब स्रोत से बैश बनाया गया है)।
जहां तक मैं बता सकता हूं, बैश के किसी भी जारी संस्करण ने /dev/stdout
एट अल बिना शर्त के विशेष हैंडलिंग नहीं बनाई है - जब तक कि कुछ वितरण ने इसे पैच नहीं किया है।
तो एक और वर्कअराउंड (जो मैंने कोशिश नहीं की है) बैश स्रोतों को हथियाने के लिए होगा , redir.c
विशेष /dev/*
हैंडलिंग को बिना शर्त बनाने के लिए संशोधित करें , और आपके सिस्टम के साथ आए एक के बजाय अपने पुनर्निर्माण संस्करण का उपयोग करें। यह शायद ओवरकिल है, हालांकि।
सारांश :
आपका ओएस, मेरी तरह, स्वामित्व और अनुमतियों को /dev/stdout
और /dev/stderr
सही तरीके से नहीं संभाल रहा है। बैश माना जाता है कि वे इन नामों को विशेष रूप से पुनर्निर्देशन में मानते हैं, लेकिन वास्तव में ऐसा केवल तभी होता है जब फाइलें मौजूद नहीं होती हैं। अगर यह सही नहीं है /dev/stdout
और /dev/stderr
काम नहीं करेगा । यह समस्या केवल तब दिखाई देती है जब आप su
किसी अन्य खाते या कुछ समान करते हैं; यदि आप किसी खाते में प्रवेश करते हैं, तो अनुमति सही है।
ls -l /dev/stdout /dev/stderr
औरls -lL /dev/stdout /dev/stderr
?