स्क्रिप्ट को चलाने से कैसे रोकें अगर यह रूट नहीं है (और गूंज "रूट के रूप में नहीं चल रहा है! बाहर निकल रहा है ...")


17

यहाँ मेरा स्रोत है:

#!/bin/bash

echo "Running script to free general cached memory!"
echo "";
echo "Script must be run as root!";
echo "";
echo "Clearing swap!";
swapoff -a && swapon -a;
echo "";
echo "Clear inodes and page file!";
echo 1 > /proc/sys/vm/drop_caches;
echo "";

यह कैश और सामान को साफ करता है, और यह गूँजता है कि इसे टर्मिनल में रूट के रूप में चलाने की आवश्यकता है। मैं मूल रूप से केवल स्क्रिप्ट को चलाना बंद करना चाहता हूं यदि यह पता लगाता है कि इसे रूट के रूप में निष्पादित नहीं किया जा रहा है।

उदाहरण:

"Running script to free general cached memory!"
"Warning: script must be run as root or with elevated privileges!"
"Error: script not running as root or with sudo! Exiting..."

यदि ऊंचे विशेषाधिकारों के साथ चलाया जाता है, तो यह सामान्य रूप से चलता है। कोई विचार? धन्यवाद!



2
@ मर्मू, सिवाय इसके कि अन्य प्रश्न इसके विपरीत है: यदि रूट के रूप में चल रहा है तो स्क्रिप्ट को विफल करें।
स्टीफन चेज़लस

3
@ StéphaneChazelas आह, मेरा बुरा। वापस लिया गया
muru

एक विकल्प के rootरूप में के रूप में के rootसाथ चलना चाहिए कि सभी आदेशों को उपसर्ग उपसर्ग द्वारा निष्पादित कार्य की मात्रा को सीमित करना है sudo
रीयरियरपोस्ट

जवाबों:


47
#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

रूट उपयोगकर्ता के पास UID 0 ("रूट" खाते के नाम की परवाह किए बिना) है। यदि प्रभावी UID द्वारा लौटाया गया id -uशून्य नहीं है, तो उपयोगकर्ता रूट विशेषाधिकारों के साथ स्क्रिप्ट निष्पादित नहीं कर रहा है। id -ruवास्तविक आईडी के खिलाफ परीक्षण करने के लिए उपयोग करें ( स्क्रिप्ट को लागू करने वाले उपयोगकर्ता का यूआईडी )।

$EUIDस्क्रिप्ट में उपयोग न करें क्योंकि यह एक अप्रकाशित उपयोगकर्ता द्वारा संशोधित किया जा सकता है:

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

यदि किसी उपयोगकर्ता ने ऐसा किया है, तो यह जाहिर तौर पर विशेषाधिकार वृद्धि के लिए नेतृत्व नहीं करेगा, लेकिन हो सकता है कि स्क्रिप्ट में आदेशों को वह करने में सक्षम न हो जो वे करने वाले हैं और गलत मालिक के साथ बनाई जा रही फाइलें आदि।


1
नोट: सोलारिस 5.10 पर, /bin/id -uदेता है/bin/id: illegal option -- u Usage: id [-ap] [user]
jrw32982

1
@ jrw32982 सोलारिस पर POSIX उपयोगिताओं तक पहुंच पाने के लिए /usr/xpg4/binआपके पास जल्दी होना चाहिए $PATH
Kusalananda

1
मुद्दा यह है कि का -uविकल्प idसार्वभौमिक नहीं है और इसलिए यह समाधान केवल उस चेतावनी के साथ सार्वभौमिक है जो कि idआपके PATH में POSIX संस्करण पहले होना चाहिए।
jrw32982

1
@ jrw32982 आपकी स्क्रिप्ट सोलारिस पर सही POSIX उपयोगिताओं को लेने के लिए, $PATHस्क्रिप्ट के शीर्ष पर संशोधित करें ताकि वह /usr/xpg4/binपहले हो /bin। यदि आप गैर-पॉसिक्स का उपयोग करने पर जोर देते हैं id, तो जाहिर है कि आपको अधिक पोर्टेबल समाधान के साथ आना होगा।
Kusalananda

1
@Harry हाँ, इसलिए स्क्रिप्ट PATH=$( getconf PATH )कुछ अन्य स्पष्ट डिफ़ॉल्ट पथ का उपयोग या सेट कर सकती है, या कॉल करने के लिए एक स्पष्ट पथ का उपयोग कर सकती है id
Kusalananda

19

मुझे लगता है कि आप जो चाहते हैं वह यह जांचने के लिए है कि आपके पास सुपर-उपयोगकर्ता विशेषाधिकार हैं, अर्थात आपकी प्रभावी उपयोगकर्ता आईडी 0 है।

zshऔर चर bashमें उपलब्ध है $EUID, तो आप कर सकते हैं:

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

किसी भी POSIX जैसे गोले के साथ, आप idमानक कमांड का उपयोग कर सकते हैं :

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

ध्यान दें कि सभी id -unया whoamiया $USERNAMEचर में zshआपको यूआईडी के लिए पहला उपयोगकर्ता नाम मिलेगा । आईडी 0 के साथ अन्य उपयोगकर्ता वाले सिस्टम पर, यह नहीं हो सकता हैroot भले ही यह प्रक्रिया उसी के वंशज हो जो के रूप में प्रमाणित किया गया हो root

$USERहैं आम तौर पर आप उपयोगकर्ता जो प्रमाणीकृत है, लेकिन यह पर भरोसा काफी भंगुर है दे। यह शेल द्वारा सेट नहीं किया गया है, लेकिन आमतौर पर प्रमाणीकरण कमांड द्वारा निर्धारित किया जाता है (जैसे login, suजीएनयू / लिनक्स सिस्टम पर, जरूरी नहीं कि अन्य) sudo, sshd(कम से कम एक से)। हालांकि यह हमेशा नहीं होता है (यूआईडी को बदलना स्वचालित रूप से उस चर को सेट नहीं करता है, इसे स्पष्ट रूप से यूआईडी को बदलने वाले एप्लिकेशन द्वारा किया जाना है) और इसे शेल के वंश में किसी अन्य प्रक्रिया द्वारा संशोधित भी किया जा सकता था। $LOGNAME, एक ही चेतावनी के साथ अधिक विश्वसनीय है क्योंकि यह POSIX द्वारा निर्दिष्ट है (मूल रूप से FIPS 151-2 से)


12

आप वर्तमान उपयोगकर्ता की जांच $USERया उपयोग कर सकते हैं whoami

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

1
एन पी। मेरा सुझाव है कि बस बैश मैनुअल [ gnu.org/software/bash/manual/bashref.html] के माध्यम से सीधे पढ़ने का सुझाव है । यह वास्तव में आश्चर्यजनक रूप से आसान तैयार है। इस जवाब के लिए विशेष रूप से मैं संदर्भित करने का सुझाव देता हूं: 3.2.4.2 Conditional Constructs 3.5.4 Command Substitution
जेसी_बी

9
विकल्प के id -uसाथ या बिना कमांड, -nwhoami का उपयोग करने के लिए एक विकल्प है। एक एन के बिना और शून्य की तुलना करने के लिए कर्नेल वास्तव में कर रहा है परीक्षण के लिए एक बेहतर मैच है। सभी कर्नेल के बारे में परवाह है आईडी, पासवर्ड फ़ाइल से नाम नहीं है।
इकारस

6
मेरा मानना ​​है कि उपयोग $(id -u)करना बेहतर है। कुछ (दुर्भावनापूर्ण) मामलों में, $USERगलत हो सकता है।
बेसिल स्टारीनेवविच

1
@Jesse_b द्वारा प्रदान किए गए लिंक में रुचि रखने वालों के लिए: एक टाइपो है। यह होना चाहिए gnu.org/software/bash/manual/bashref.html
Kryten

1
कुछ सिस्टम "रूट" का उपयोग नहीं करते हैं क्योंकि विशेषाधिकारित खाते का नाम uid 0. क्यूएनएपी स्प्रिंग्स एक के रूप में दिमाग में है। इसलिए आपको केवल uid 0 की जांच करनी चाहिए, न कि रूट अकाउंट के नाम की।
रोआमा

10

आप वास्तव में क्या चाहते हैं यह निर्धारित करना है कि क्या आपके पास इन कार्यों को करने के लिए पहुंच है। यह जाँचने के लिए बुरा अभ्यास माना जाता है कि आप इसके बदले में रूट हैं या नहीं।

यदि सिस्टम को एक गैर-रूट उपयोगकर्ता को स्वैप और पेज कैश को संशोधित करने की अनुमति देने के लिए कॉन्फ़िगर किया गया है, तो उस उपयोगकर्ता को आपकी स्क्रिप्ट चलाने के लिए क्यों नहीं मिलना चाहिए?

इसके बजाय, आप बस एक असफल संदेश के साथ ऑपरेशन और निकास की कोशिश कर सकते हैं यदि यह विफल रहता है:

if ! ( swapoff -a && swapon -a )
then
  echo "Failed to clear swap (rerun as root?)" >&2
  exit 1
fi

if ! echo 1 > /proc/sys/vm/drop_caches
then 
  echo "Failed to free page cache (rerun as root?)" >&2
  exit 1
fi

एक गैर-रूट उपयोगकर्ता स्वैप को बंद कर रहा है?
कुसलानंद

2
हाँ। आप इसे SELinux के साथ सेट कर सकते हैं। इसी तरह, आप इसे करने से एक रूट प्रक्रिया को अक्षम कर सकते हैं।
वह अन्य व्यक्ति

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

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