bash: / dev / stderr: अनुमति अस्वीकृत


19

एक नए रिलीज़ संस्करण में अपग्रेड करने के बाद, मेरी bashस्क्रिप्ट में गलतियाँ होने लगीं:

bash: /dev/stderr: Permission denied

पिछले संस्करणों में बैश हैं आंतरिक रूप से पहचान उन फ़ाइल नाम (जिसके कारण इस सवाल का डुप्लिकेट नहीं है यह एक ) और सही बात (टीएम) करना , तथापि, यह अब काम रुक गया है। मैं अपनी स्क्रिप्ट को फिर से सफलतापूर्वक चलाने में सक्षम होने के लिए क्या कर सकता हूं?

मैंने समूह में स्क्रिप्ट चलाने वाले उपयोगकर्ता को जोड़ने की कोशिश की है tty, लेकिन इससे कोई फर्क नहीं पड़ता (लॉग आउट करने और वापस आने के बाद भी)।

मैं बिना समस्या के कमांड लाइन पर इसे पुन: पेश कर सकता हूं:

$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release

एक पुराने सिस्टम पर (Ubuntu 10.04):

$ echo $BASH_VERSION
4.1.5(1)-release

1
के उत्पादन में क्या है ls -l /dev/stdout /dev/stderrऔर ls -lL /dev/stdout /dev/stderr?
कीथ थॉम्पसन

@ कीथ: मेरे संपादित प्रश्न देखें। क्या इसका मतलब यह है कि बैश ने इस की आंतरिक हैंडलिंग को पूरी तरह से छोड़ दिया है? पुराने सिस्टम में ये सिमलिंक मौजूद नहीं थे और फिर भी कोड समस्या के बिना काम करता था। ध्यान दें, यह sudo su username2 -... के माध्यम से प्रतिरूपण चल रहा है ...
0xC0000022L

आप किस संस्करण का उपयोग कर रहे हैं? echo $BASH_VERSION
जिप्पी

1
पुराने और नए संस्करण क्या हैं (आपके ओएस के पहले और बाद में और बैश के?
कीथ थॉम्पसन

जवाबों:


41

मुझे नहीं लगता कि यह पूरी तरह से एक बैश मुद्दा है।

एक टिप्पणी में, आपने कहा कि आपने यह त्रुटि देखी थी

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किसी अन्य खाते या कुछ समान करते हैं; यदि आप किसी खाते में प्रवेश करते हैं, तो अनुमति सही है।


TTY का स्वामित्व बदलना चाहिए। यही ConsoleKit (उर्फ pam_ck_connector.soके लिए है)।
मिकेल

वास्तव में, मैं गलत हो सकता है। और खोदना पड़ेगा।
मिकेल

मेरे सिस्टम पर, /proc/self/fd/1इसकी अनुमतियाँ अद्यतन की जा रही हैं, लेकिन यह एक सहिष्णु है, क्योंकि यह बेकार है। Fedora पर भी होता है, जो ConsoleKit को नियमबद्ध करता है।
मिकेल

1

वास्तव में इसका कारण यह है कि udv ने विशेष रूप से अनुमतियों को 0620 tty उपकरणों पर सेट किया है और su न तो स्वामित्व या अनुमतियों को बदलता है और न ही इसे बदलना चाहिए। मेरे विचार में यह हमें ऐसी स्थिति में छोड़ देता है जो गैर-पोर्टेबल बनाता है।

सरल उपाय यह है कि आप "मेसग y" को / etc / प्रोफाइल (या जो भी शीर्ष स्तर की प्रोफ़ाइल आप उपयोग करना चाहते हैं) में डाल दें क्योंकि यह आपके tty डिवाइस की अनुमतियों को 0622 में बदल देता है। मैं वास्तव में ऐसा नहीं करता लेकिन यह शायद बेहतर है udv नियमों को बदलने से।


"msg y" काम नहीं करता है
लुसियानो

प्रतीक्षा करें ... हो सकता है कि बैश के लिए खोज कई फिल्नामों को विशेष रूप से संभालती है जब उन्हें बैश के मैन पेज में पुनर्निर्देशन में उपयोग किया जाता है
0xC0000022L

0

लंबे समय से लिनक्स यूजर के रूप में मैंने हाल ही में एक नया उबंटू 64 बिट 12.04 एलटीएस सिस्टम स्थापित किया था और इस बात के लिए रहस्यमयी था कि मेरी बैश स्क्रिप्ट काम नहीं कर रही थी - अनुमति से इनकार कर दिया गया था - और मुझे बाद में यह धागा मिला। मुझे लगा कि नए OS में कुछ समस्या के कारण समस्या हो सकती है।

अंत में यह पता चला कि मैंने अपनी /homeनिर्देशिका पर अनुमतियाँ सेट करने के लिए एक UI उपकरण का उपयोग किया था, और समस्या ड्राइव- संबंधी थी। यह सुनिश्चित करने के लिए, मैंने एक tempनिर्देशिका बनाई /optऔर पाया कि मेरी स्क्रिप्ट वहाँ से ठीक चलेगी। एक बार जब मैंने /homeड्राइव की अनुमति तय की तो सब कुछ वापस सामान्य हो गया।

एक छोटा सा रहस्य सुलझ गया। आह


2
यह एक अलग त्रुटि रही होगी। / घर में किसी चीज़ को संशोधित करने से / देव प्रभावित नहीं होता है।
ott--

-1

यह एक पुराना सवाल है, लेकिन मुझे लगता है कि अभी भी बहुत प्रासंगिक है, इसलिए यहां समाधान है जो मैंने पाया है जिसका उल्लेख यहां नहीं किया गया है।

मुझे इस सवाल का सामना करना पड़ा क्योंकि मैंने 'su' स्विच्ड अकाउंट को कमांड को bash में इस तरह से देखा है:

echo test > /dev/stderr

चूँकि सब मैं करने की कोशिश कर रहा हूँ stder को stdout पर पुनर्निर्देशित करना, निम्नलिखित समान प्राप्त करता है, और यह 'su' स्विच किए गए खाते में भी काम करता है:

echo test 1>&2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.