शेल स्क्रिप्ट में "सुडो सु" बाकी स्क्रिप्ट को रूट के रूप में क्यों नहीं चलाता है?


36

एक नमूना स्क्रिप्ट नीचे दी जा सकती है:

#!/bin/bash
sudo su
ls /root

./test.shसामान्य उपयोगकर्ता के रूप में उपयोग करने के बजाय, lsसुपर उपयोगकर्ता के रूप में चलाएं और बाहर निकलें, यह रूट पर स्विच करता है; और जब मैं लॉगआउट करता हूं, तो यह ls /rootसामान्य उपयोगकर्ता के रूप में निष्पादित होता है।

क्या कोई मुझे इसके बारे में तंत्र के बारे में बता सकता है?


13
sudo suमेरी आँखों को चोट पहुँचाता है।
जिलेटेन

इसका उपयोग इसलिए किया जाता है क्योंकि लोग sudo को अच्छी तरह से नहीं जानते हैं, और इसलिए उन्हें सिस्टम पर su चलाने का एक तरीका चाहिए जहां रूट को जानबूझकर दूषित पासवर्ड द्वारा सुरक्षित किया जाता है। लेकिन हाँ सुडो "सु के उपयोग को कम करता है"।
जोहान

1
आप सिर्फ उपयोग नहीं कर सकते sudo -s, हालांकि?
जो Z.

@ जोहान, मैं अक्सर उपयोग करता sudo suहूं क्योंकि मैं उन विकल्पों की suतुलना में अधिक अभ्यस्त हूं, जिनमें से मैं हूं sudo। मैं सूडो के विकल्पों को अच्छी तरह से जानता हूं, लेकिन मैं सु को तेजी से टाइप कर सकता हूं। लेकिन हां मुझे लगता है कि इसका मतलब है कि मैं सुडोल को अच्छी तरह से नहीं जानता।
user606723

1
मैंने बस sudo man पेज चेक किया। ऐसा प्रतीत होता है sudo -iके लिए समान है su -, जबकि sudo -sतरह संचालित su(पानी का छींटा के बिना)
जोहान

जवाबों:


49

एक स्क्रिप्ट में कमांड एक-एक करके, स्वतंत्र रूप से निष्पादित होते हैं। स्क्रिप्ट ही स्क्रिप्ट में सभी आदेशों के जनक के रूप में है, एक और स्वतंत्र प्रक्रिया है और सु कमांड इसे रूट में परिवर्तित नहीं कर सकता है: र कमांड विशेष रूट विशेषाधिकार के साथ एक नई प्रक्रिया बनाता है।

उसके बाद su कमांड पूरी होती है, मूल प्रक्रिया, जो अभी भी उसी उपयोगकर्ता के रूप में चल रही है, बाकी स्क्रिप्ट को निष्पादित करेगी।

आप जो करना चाहते हैं, वह एक रैपर स्क्रिप्ट लिखें। उदाहरण के लिए विशेषाधिकार प्राप्त कमांड मुख्य स्क्रिप्ट में जाते हैं~/main.sh

#!/bin/sh
ls /root

रैपर स्क्रिप्ट मुख्य स्क्रिप्ट को रूट अनुमतियों के साथ कॉल करती है, जैसे

#!/bin/sh
su -c ~/main.sh root

इस प्रक्रिया को लॉन्च करने के लिए, आप रैपर को चलाते हैं, जो उपयोगकर्ता को रूट उपयोगकर्ता पर स्विच करने के बाद मुख्य स्क्रिप्ट लॉन्च करता है।

इस रैपर तकनीक का उपयोग स्क्रिप्ट को अपने आसपास के आवरण में बदलने के लिए किया जा सकता है। मूल रूप से यह देखने के लिए जांचें कि क्या यह रूट के रूप में चल रहा है, यदि नहीं, तो खुद को फिर से लॉन्च करने के लिए "सु" का उपयोग करें।

$ 0 एक स्क्रिप्ट बनाने का एक आसान तरीका है, जो स्वयं को संदर्भित करता है, और whoami कमांड हमें बता सकती है कि हम कौन हैं (क्या हम जड़ हैं?)

तो अंतर्निहित आवरण के साथ मुख्य स्क्रिप्ट बन जाती है

#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root

निष्पादन के उपयोग पर ध्यान दें। इसका अर्थ है "इस कार्यक्रम को प्रतिस्थापित करें", जो प्रभावी रूप से अपने निष्पादन को समाप्त करता है और नए कार्यक्रम की शुरुआत करता है, जो सु द्वारा शुरू किया गया है, जड़ से, ऊपर से चलाने के लिए। प्रतिस्थापन उदाहरण "रूट" है, इसलिए यह सही पक्ष को निष्पादित नहीं करता है ||


1
fwiw, इस बिंदु पर एक परिशिष्ट। अगर मैं इसकी तरह एक स्क्रिप्ट लिख रहा था, तो मैं शुरुआत में केवल एक बयान करूंगा जो $ EUID की जांच करता है और यदि यह शून्य sudo ही नहीं है और बाहर निकलता है, अन्यथा स्क्रिप्ट निष्पादन के साथ जारी रखें।
ब्राचली

सहमत, और मैं इसे समझाने के लिए उत्तर को अपडेट करूंगा।
जोहान

2
शायद यह थोड़ा पुरातन है, लेकिन मैं हर निष्पादन योग्य के लिए पूर्ण पथ से प्यार करता हूं, इसलिए कोई व्यक्ति ~ / main.sh स्क्रिप्ट को कुछ नापाक में नहीं बदल सकता है। स्क्रिप्ट के USER भाग पर हमला करना
Artifex

2
आप उन दलीलों को भी पकड़ना चाहते हैं जिन्हें $ * के संदर्भ में शामिल करके इसे पारित किया गया था
Bratchley

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

20

स्क्रिप्ट में निम्नलिखित का उपयोग करें।

sudo su <<HERE
ls /root
HERE

HERE ब्लॉक के बीच का कोड रूट के रूप में चलाया जाएगा।


6
sudo suदो कार्यक्रमों को बुला रहा है। का उपयोग करें sudo -s <<HEREDOCया su user <<HEREDOC... बेवकूफ 5 मिनट की सीमा।
जोहान

6

आगे तर्क के बिना suरूट के लिए लॉगिन शेल चलाएंगे। आपकी स्क्रिप्ट की पहली पंक्ति वास्तव में यही करती है। जब आप बाहर निकलते हैं, तो लॉगिन शेल बंद हो जाता है, सु रिटर्न और आपकी स्क्रिप्ट का निष्पादन जारी रहता है, जो दूसरी पंक्ति के साथ है ls /root:। मुझे लगता है कि आप बस sudo ls /rootवही कर सकते हैं जो आप चाहते हैं।


हाँ, मुझे पता है कि मैं यह कर सकता हूँ ls, लेकिन यह सिर्फ एक नमूना है। वास्तव में मुझे रूट विशेषाधिकार के साथ बहुत कुछ करने की आवश्यकता है :-) तो मुझे @ अंकित का जवाब पसंद है।
होंग्क्सू चेन

1

एक बार जब आप सुपर उपयोगकर्ता sudo suके प्रभावी userid (euid=EUID)के साथ एक नई प्रक्रिया को फायर करते हैं , इसलिए हमारे पास (pid=PID)एक ही टर्मिनल से जुड़े विभिन्न प्रोसेस आईडी पर चलने वाले नए बैश हैं (tname=TTY)

व्याख्या

मान लें कि फायरिंग के बाद ps -A | grep bashआपके पास 21460 pts/2 00:00:00 bashआउटपुट के रूप में है। अब, जब आप ./test.shदोनों कमांड निष्पादित करते हैं sudo suऔर ls /rootस्पूल किया जाएगा PID 21460। निष्पादन के बाद जब आपके पास फिर से rootसक्रिय उपयोगकर्ता हिट ps -A | grep bashहोता है, तो आप एक नए बैश को चालू देखेंगे PID say, 21570। से बाहर निकलने से root bashनव कांटेदार बैश को मारना होगा user's bashऔर इसलिए ls /rootशीघ्र रिहा करने से पहले स्पूल कमांड को निष्पादित करना होगा ।


यदि su या sudo का उपयोग bash (या कहीं और) में "लगातार" किया गया, तो यह हल होने की तुलना में कई और अधिक समस्याएं पैदा करेगा। सुरक्षा और सुरक्षा के लिए आपको न्यूनतम संभव करना होगा। Su और sudo (सुरक्षा के अलावा!) होने का मुख्य बिंदु यह है कि आपको ध्यान से सोचना चाहिए कि रूट विशेषाधिकारों की क्या आवश्यकता है।
जो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.