bash - सुडो बिल्ली क्यों अनुमति देता है लेकिन सुडो विम ठीक काम करता है?



shell echo (4)

जैसा कि @geekosaur समझाया गया है, शेल कमांड चलाने से पहले पुनर्निर्देशन करता है। जब आप इसे टाइप करते हैं:

sudo foo >/some/file

आपकी वर्तमान खोल प्रक्रिया स्वयं की प्रतिलिपि बनाता है जो पहले लिखने के लिए /some/file खोलने की कोशिश करता है, फिर उस फ़ाइल डिस्क्रिप्टर को अपने मानक आउटपुट बनाता है, और केवल तब ही sudo निष्पादित करता है।

यदि आपको अनुमति है (सूडोयर कॉन्फ़िगर अक्सर चलने वाले गोले को रोकते हैं), तो आप ऐसा कुछ कर सकते हैं:

sudo bash -c 'foo >/some/file'

लेकिन मुझे सामान्य रूप से एक अच्छा समाधान मिलना है | sudo tee बजाय > और | sudo tee -a | sudo tee -a बजाय >> । यह विशेष रूप से उपयोगी है अगर पुनर्निर्देशन एकमात्र कारण है जिसे मुझे पहले स्थान पर sudo चाहिए; आखिरकार, रूट के रूप में अनावश्यक रूप से चल रही प्रक्रियाएं ठीक से बचने के लिए sudo बनाई गई थीं। और जड़ के रूप में echo चलाना सिर्फ मूर्ख है।

echo '[archlinuxfr]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$arch' | sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | sudo tee -a /etc/pacman.conf >/dev/null

मैंने अंत में > /dev/null को जोड़ा क्योंकि tee नामित फ़ाइल और उसके मानक आउटपुट दोनों के लिए अपना आउटपुट भेजता है, और मुझे इसे अपने टर्मिनल पर देखने की आवश्यकता नहीं है। ( tee कमांड एक भौतिक पाइपलाइन में "टी" कनेक्टर की तरह काम करता है, जहां वह इसका नाम प्राप्त करता है।) और मैंने युगल ( " ... " ) के बजाय सिंगल कोट्स ( ' ... ' ) पर स्विच किया ताकि वह सब कुछ शाब्दिक है और मुझे $arch में $arch सामने बैकस्लैश डालना नहीं था।

तो sudo का उपयोग कर रूट के रूप में फ़ाइलों को लिखने का ख्याल रखता है। अब शेल स्क्रिप्ट में न्यूलाइन युक्त टेक्स्ट आउटपुट करने के तरीकों पर एक लंबी खुदाई के लिए। :)

सबसे पहले, आप सबको एक साथ सबको में एक साथ जोड़ सकते हैं, इसलिए आपको केवल एक बार पुनर्निर्देशन करना होगा:

(echo '[archlinuxfr]
 echo 'Server = http://repo.archlinux.fr/$arch'
 echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null

या echo बजाय printf उपयोग करें, ताकि आप सीधे नई स्ट्रिंग को स्ट्रिंग में एम्बेड कर सकें \n :

printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' | 
  sudo tee -a /etc/pacman.conf >/dev/null

bash , आप echo -e साथ एक ही परिणाम प्राप्त कर सकते हैं:

# BASH ONLY - NOT RECOMMENDED
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' | 
  sudo tee -a /etc/pacman.conf >/dev/null

लेकिन जब आप कोशिश करते हैं तो अधिकांश गोले सिर्फ आउटपुट करेंगे, इसलिए इसकी अनुशंसा नहीं की जाती है।

printf और echo -e दोनों के साथ, कमांड स्ट्रिंग के रूप में कमांड को क्या मिलता है, जिसमें ए शाब्दिक बैकस्लैश होता है, जहां आप टाइप करते हैं, वहां एक शाब्दिक एन के बाद \n , और यह कमांड प्रोग्राम ( printf या echo के अंदर कोड) का अनुवाद करने के लिए है एक नई लाइन में। कई आधुनिक गोले में, आपके पास एएनएसआई कोट्स $' ... ' का उपयोग करने का विकल्प है, जो कमांड प्रोग्राम को कभी भी स्ट्रिंग को देखने से पहले \n शाब्दिक न्यूलाइन में अनुक्रमों का अनुवाद करेगा, जिसका अर्थ यह है कि ऐसे तार किसी भी कमांड के साथ काम करते हैं:

echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' | 
  sudo tee -a /etc/pacman.conf >/dev/null

लेकिन, echo -e से अधिक पोर्टेबल होने पर, एएनएसआई उद्धरण अभी भी एक गैर-पॉज़िक्स एक्सटेंशन हैं।

ऐसा करने का मेरा पसंदीदा तरीका यहां एक दस्तावेज़ का उपयोग करना होगा और पूरी तरह से echo या printf की आवश्यकता से बचें:

sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch

EOF

https://ffff65535.com

मैं अपने आर्क की pacman.conf फ़ाइल में एक भंडार स्रोत के अतिरिक्त स्वचालित करने की कोशिश कर रहा हूं लेकिन मेरी खोल स्क्रिप्ट में echo कमांड का उपयोग कर रहा हूं। हालांकि, यह इस तरह विफल रहता है: -

sudo echo "[archlinuxfr]" >> /etc/pacman.conf
sudo echo "Server = http://repo.archlinux.fr/\$arch" >> /etc/pacman.conf
sudo echo " " >> /etc/pacman.conf

-bash: /etc/pacman.conf: Permission denied

यदि मैं vim का उपयोग कर मैन्युअल रूप से /etc/pacman.conf में परिवर्तन करता हूं, तो कर रहा हूं

sudo vim /etc/pacman.conf

और विम विजिट के साथ :wq , सब कुछ ठीक काम करता है और मेरे pacman.conf को "अनुमति अस्वीकार" शिकायतों के बिना मैन्युअल रूप से अपडेट किया गया है।

ऐसा क्यों है? और मैं काम करने के लिए sudo echo कैसे प्राप्त करूं? (बीटीडब्ल्यू, मैंने sudo cat भी उपयोग करने की कोशिश की लेकिन अनुमति के साथ असफल रहा)


समस्या यह है कि पुनर्निर्देशन को आपके मूल खोल से संसाधित किया जा रहा है, न कि sudo द्वारा। शैल दिमाग पढ़ने में सक्षम नहीं हैं और यह नहीं जानते कि वह विशेष >> sudo और इसके लिए नहीं।

आपको:

  1. पुनर्निर्देशन उद्धरण (इसलिए यह sudo) को पारित किया जाता है sudo)
  2. और sudo -s उपयोग करें (ताकि sudo उद्धृत पुनर्निर्देशन को संसाधित करने के लिए एक खोल का उपयोग कर सके।)

चरण 1 एक बैश फ़ाइल में एक फ़ंक्शन बनाएं

## write_pacman.sh
write_pacman(){
 sudo tee -a /etc/pacman.conf > /dev/null << 'EOF'
  [archlinuxfr]
  Server = http://repo.archlinux.fr/\$arch
 EOF
}

'EOF' $arch वैरिएबल की व्याख्या नहीं करेगा।

एसटीई 2 स्रोत बैश फ़ाइल

$ source write_pacman.sh

चरण 3 निष्पादित समारोह

$ write_pacman

sudo bash -c 'echo "[archlinuxfr]" >> /etc/pacman.conf'




cat