यदि रूट के रूप में चलाया जा रहा है तो कोई स्क्रिप्ट कैसे जांच सकती है?


104

मैं एक साधारण बैश स्क्रिप्ट लिख रहा हूं, लेकिन मुझे यह जांचने की आवश्यकता है कि यह रूट के रूप में चलाया जा रहा है या नहीं। मुझे पता है कि ऐसा करने का एक बहुत सरल तरीका है, लेकिन मुझे नहीं पता कि कैसे।

बस स्पष्ट होना:
एक स्क्रिप्ट foo.sh लिखने का एक सरल तरीका क्या है , ताकि कमांड ./foo.shआउटपुट 0और कमांड sudo ./foo.shआउटपुट हो 1?

जवाबों:


148
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 
   exit 1
fi

7
मैं इस एक कारण को स्वीकार कर रहा हूं (कुछ परीक्षण के बाद) सिस्टम वैरिएबल का उपयोग करके EUID एक कमांड (id -u) चलाने की तुलना में तेजी से (लगभग 100 गुना) निकला, लेकिन सभी जवाबों ने बहुत अच्छा काम किया।
मालाबार

18
इसके अलावा, $UIDऔर $EUIDbashisms हैं। मर्ली पोज़िक आज्ञाकारी गोले में वे चर नहीं होते हैं और आपको id(1)इसके बजाय उपयोग करने की आवश्यकता होती है ।
डेविड फ़ॉस्टर

3
bash स्क्रिप्ट में, आप @ geirha की टिप्पणीif ((EUID)); then देख सकते हैं
jfs

7
@ और: वेरीएबल्स पास किए जाने से पहले प्रतिस्थापित किए जाते हैं sudo। यदि आप दौड़ते हैं sudo sh -c 'echo $EUID'तो आप अपने अपेक्षित परिणाम देखेंगे।
एम। डुडले

6
@ और - मुझे पता है कि मैं यहाँ देर से जा रहा हूँ, लेकिन बाद के लिए: $EUIDएक बैशवाद है (जैसा कि @DavidFoerster द्वारा ऊपर उल्लेख किया गया है), और आपकी /bin/shसबसे अधिक संभावना है /bin/dash, नहीं /bin/bashsudo bash -c 'echo $EUID'अपेक्षित परिणाम देगा।
एड्रियन गंटर

118

एक रूट उपयोगकर्ता को "रूट" नाम देने की आवश्यकता नहीं है। whoamiउपयोगकर्ता आईडी के साथ पहला उपयोगकर्ता नाम लौटाता है 0$USERउपयोगकर्ता में लॉग इन का नाम है, जिसमें उपयोगकर्ता आईडी हो सकती है 0, लेकिन एक अलग नाम है।

यह जांचने के लिए एकमात्र विश्वसनीय कार्यक्रम है कि खाता रूट के रूप में लॉग इन है या नहीं:

id -u

मैं प्रभावी उपयोगकर्ता आईडी के -uलिए उपयोग करता हूं , वास्तविक उपयोगकर्ता आईडी के लिए नहीं । अनुमतियाँ प्रभावी उपयोगकर्ता आईडी द्वारा निर्धारित की जाती हैं , वास्तविक नहीं ।-r

टेस्ट

/etc/passwd0दिए गए क्रम में उपयोगकर्ता आईडी के साथ निम्नलिखित उपयोगकर्ता नाम हैं :

rootx
root2

में लॉग इन किया root2, अगले परिणाम देता है:

  • whoami: rootx
  • echo $USER: root2(यदि खाली वातावरण में कार्यक्रम शुरू किया गया था, तो यह एक रिक्त स्ट्रिंग देता है, जैसे env -i sh -c 'echo $USER')
  • id -u: 0 जैसा कि आप देख सकते हैं, इस चेक में अन्य प्रोग्राम विफल हो गए, केवल id -uपास हुए।

अद्यतन स्क्रिप्ट इस तरह दिखाई देगी:

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   echo "I am not root!"
   exit 1
fi

5
आपको id -ubash askubuntu.com/questions/30148/…
jfs

5
मैं हमेशा संभव के रूप में दुभाषिया के रूप में sh( dash) का उपयोग करते हुए पोसिक्स के अनुरूप रहने की कोशिश करता हूं bash। लेकिन अच्छा शॉट, एक और कांटा बचाता है :)
लेकेनस्टाइन

थोड़ी देर ठंडी रहने के बाद, मैं वापस आया और एक नज़र देखा। Lekensteyn की विधि वास्तव में बेहतर प्रतीत होती है। उसका उत्तर अब नया स्वीकृत उत्तर है। आप के लिए +1, लेकेनस्टीन, esp। ); हो रही है कि इस सवाल का बंद बिल्ला मुश्किल से मिलता है के लिए
थॉमस वार्ड

मेरे प्रश्न को स्वीकार करने के लिए लंबे समय तक प्रतीक्षा करने के लिए धन्यवाद: DI को इस उत्तर के लिए एक गोल्ड पॉपुलिस्ट बैज और एक कांस्य अच्छा उत्तर मिला :) मुझे आश्चर्य है कि यह प्रश्न एक दिन में कैसे लोकप्रिय, 345 बार देखा गया!
लेकेनस्टाइन

3
मैं छोटे संस्करणों को देखा है, [ -w / ]। विचार वही रहता है। ध्यान दें: कुछ विशेष परिस्थितियों में, [ -w /etc/shadow ]विफल हो जाएगा क्योंकि /etc/shadowगैर-मौजूद है, इसलिए इसके साथ दृष्टिकोण /को प्राथमिकता दी जाती है। एक बेहतर तरीका रूट अनुमतियों के लिए वास्तविक आवश्यकता की जाँच करेगा। यदि स्क्रिप्ट को लिखना है /etc/someconfig, तो जाँच लें कि क्या वह फ़ाइल लिखने योग्य है या फ़ाइल मौजूद नहीं है और /etcवह लिखने योग्य नहीं है ।
लेकेनस्टाइन

30

जैसा कि @Lekensteyn ने कहा कि आपको प्रभावी उपयोगकर्ता आईडी का उपयोग करना चाहिए। आपको id -uबैश में कॉल करने की आवश्यकता नहीं है :

#!/bin/bash

if [[ $EUID -ne 0 ]]; then
   echo "You must be root to do this." 1>&2
   exit 100
fi

@ टिप्पणी से जिरह का सुझाव अंकगणितीय मूल्यांकन का उपयोग करता है:

#!/bin/bash

if (( EUID != 0 )); then
   echo "You must be root to do this." 1>&2
   exit 100
fi

7
सामान्य तौर पर किसी को ((..))परीक्षण नंबरों के लिए, और [[..]]स्ट्रिंग्स और फ़ाइलों के परीक्षण के लिए उपयोग करना चाहिए , इसलिए मैं if (( EUID != 0 )); thenइसके बजाय, या बसif ((EUID)); then
जिरिहा

@geirha: मैंने आपका सुझाव जोड़ दिया है।
jfs

2
EUIDबनना चाहिए $EUID। उपयोग करने के बजाय (( $EUID != 0 )), उपयोग करें [ $EUID != 0 ]। इसके साथ dashभी काम होगा ।
लेकेन्स्टाइन

2
@Lekensteyn: EUIDठीक काम करता है। प्रश्न टैग bashनहीं किया गया है dash। आदेश env -i sh -c '[ $EUID != 0 ]'विफल रहता है, लेकिन env -i bash -c '(( EUID != 0 ))'काम करता है। btw, dashउबंटू stackoverflow.com/questions/5160125/… पर कुछ गैर-असिसी पात्रों के लिए काम नहीं करता है। यह 2011 है और ऐसे लोग हैं जो अन्य भाषाओं का उपयोग करते हैं।
jfs

बुरी तरह से ऊब, और परीक्षण करते हुए इस पर वापस देखने के बाद, मैं इस विधि का उपयोग $EUIDइस बिंदु से आगे के सामान के साथ यहां सूचीबद्ध करने जा रहा हूं । मैंने परिणामस्वरूप उत्तर को बदल दिया है।
थॉमस वार्ड

20

आप whoamiकमांड का उपयोग करके इसे पूरा कर सकते हैं , जो वर्तमान उपयोगकर्ता को लौटाता है:

#!/bin/bash

if [ `whoami` != 'root' ]
  then
    echo "You must be root to do this."
    exit
fi

...

You must be root to do this.यदि वर्तमान उपयोगकर्ता नहीं है तो ऊपर चल रहा है प्रिंट होगा root


नोट: कुछ मामलों में एक विकल्प केवल $USERचर की जांच करना है:

if [ $USER != 'root' ]

मैं कोड पर एक नज़र डालूंगा, देखूंगा कि क्या यह स्क्रिप्ट को विफल या कुछ और नहीं बनाता है। अगर यह काम करता है, मैं अपने जवाब :) स्वीकार करेंगे
थॉमस वार्ड

4
@ जॉर्ज एडिसन: मैं उपयोग करने के खिलाफ सलाह देता हूं $USER, खासकर इस तरह से। $USERलॉगिन शेल द्वारा सेट किया गया है, यह कार्यक्रम ( env -i sh -c 'echo $USER') के लिए आवश्यक प्रचार नहीं करता है । इस तरह, $USERखाली है और एक सिंटैक्स त्रुटि होती है।
लेकेनस्टाइन

1
@Lekensteyn न केवल $USERशेल द्वारा सेट किया गया है, यह भी कुछ ऐसा है जो स्पूफ करना आसान है। हूमी वास्तविक उपयोगकर्ता को लौटाएगा।
पॉल डे व्रीज़

2
@PauldeVrieze उस जाँच को मूर्ख बनाने की क्या बात है?
htorque

1
@andrewsomething: $USERआपके शेल द्वारा व्याख्या की जाती है, आपका उदाहरण sudo sh -c 'echo $USER'सार्थक होने के लिए होना चाहिए । @ जॉर्ज: यह गलत धारणा बनाता है जो whoamiहमेशा rootयूआईडी 0. के लिए लौटेगा
sam hocevar

11

दक्षता को ध्यान में रखते हुए, आप परीक्षण कर सकते हैं, पहले, EUIDपर्यावरण चर और फिर, यदि यह मौजूद नहीं है, तो मानक idकमांड को कॉल करें :

if ((${EUID:-0} || "$(id -u)")); then
  echo You are not root.
else
  echo Hello, root.
fi

इस तरह, OR शॉर्टकट के कारण , आप इन-मेमोरी चर की क्वेरी को प्राथमिकता देते हुए एक सिस्टम कमांड को कॉल करने से बचते हैं।

कोड का पुन: उपयोग:

function amIRoot() {
  ! ((${EUID:-0} || "$(id -u)"))
}

मुझे डर है कि आपने इसे बेंचमार्क नहीं किया है, अच्छी तरह से मेरे पास है और इसमें बहुत समय लगता है id -u। इसके नीचे परिणाम के साथ बेंच स्क्रिप्ट देखें: pastebin.com/srC3LWQy
LinuxSecurityFreak


2

केवल रूट द्वारा स्क्रिप्ट को रन करने योग्य बनाने का एक सरल तरीका यह है कि स्क्रिप्ट को लाइन से शुरू किया जाए:
#!/bin/su root


1
यह मत करो। यह सीधे रूट के रूप में लॉग इन करने का प्रयास करता है, जबकि कई प्रणालियों पर sudo की आवश्यकता हो सकती है क्योंकि पूर्व निषिद्ध है। इसके अलावा, शेबंग का उद्देश्य यह है कि आपकी स्क्रिप्ट उसी के लिए चलती है, जिसके लिए इसे डिज़ाइन किया गया था, जबकि आपकी विधि स्क्रिप्ट को रूट के डिफ़ॉल्ट शेल में चलाने का कारण बनेगी, जिसकी भविष्यवाणी की नहीं जा सकती है यदि स्क्रिप्ट लेखक के अलावा किसी अन्य द्वारा चलायी जाती है। इसलिए, स्क्रिप्ट के विशेषाधिकारों को बढ़ाने के लिए शेबंग का उपयोग करने से इसकी पोर्टेबिलिटी गंभीर रूप से टूट जाएगी और कई प्रणालियों पर त्रुटियां हो सकती हैं। (सु: ऑथेंटिकेशन फेलियर)
स्टार क्रशर


1

यह स्निपेट होगा:

  • विभिन्न सत्रों की जाँच करें
  • उपयोग करने का सुझाव दें sudo !!
  • और एक त्रुटि लौटाते हैं
अगर ["$ (whoami & 2> / dev / null)"! = "root"] और& ["$ (id -un & 2> / dev / null)"! = "root"]
      फिर
      गूंज "आपको इस स्क्रिप्ट को चलाने के लिए मूल होना चाहिए!"
      गूंज "उपयोग 'sudo !!'"
      बाहर निकलें 1
फाई

1

यह उत्तर केवल एक विचार को बचाने के लिए है जो आप में से कुछ के लिए उपयोगी हो सकता है। यदि आपको स्क्रिप्ट की आवश्यकता है जो डेस्कटॉप GUI से चलाया जाता है और इसके लिए रूट विशेषाधिकारों की आवश्यकता होती है:

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   gksudo -w $0 $@
   exit
fi

#here go superuser commands, e.g. (switch intel cpu into powersave mode):
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
cpupower frequency-set -g powersave

इस तरह से आपको रूट यूजर पासवर्ड मांगते हुए अच्छी डायलॉग विंडो मिल जाएगी। जैसे कमांड-लाइन सूडो के साथ।

gksudoतो आपके सिस्टम में उपलब्ध नहीं हो सकता के साथ इसे स्थापित sudo apt-get install gksu


0

यह कोड बैश और स्टॉक बॉर्न श (फ्रीबीएसडी के तहत परीक्षण) दोनों के तहत काम करता है जो ईयूआईडी को परिभाषित नहीं करता है। यदि EUID मौजूद है, तो इसका मान लौटाया जाता है, अन्यथा 'id' कमांड चलाया जाता है। यह ऊपर दिए गए "या" उदाहरण की तुलना में छोटा है, क्योंकि यह शेल में निर्मित ": -" का उपयोग करता है।

श में जड़:

# echo $EUID

# euid=${EUID:-`id -u`}
# echo $euid
0

In bash:
[chaapala@tenfwd2 ese]$ euid=${EUID:-`id -u`}
[chaapala@tenfwd2 ese]$ echo $euid
10260
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.