Wie kann ein Skript überprüfen, ob es als root ausgeführt wird?


104

Ich schreibe ein einfaches Bash-Skript, aber ich muss überprüfen, ob es als root ausgeführt wird oder nicht. Ich weiß, dass es wahrscheinlich einen sehr einfachen Weg gibt, aber ich habe keine Ahnung, wie.

Nur um klar zu sein:
Was ist eine einfache Möglichkeit , ein Skript zu schreiben foo.sh , so dass die ./foo.shBefehlsausgänge 0und die sudo ./foo.shBefehlsausgänge 1?

Antworten:


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

7
Ich akzeptiere diese eine Ursache (nach einigen Tests), da sich herausstellte, dass die Verwendung der Systemvariablen EUID (ca. 100-mal) schneller ist als die Ausführung eines Befehls (id -u), aber alle Antworten haben hervorragend funktioniert.
Malabarba

18
Auch $UIDund $EUIDsind Bashismen. Lediglich POSIX-kompatible Shells haben diese Variablen nicht und müssen id(1)stattdessen verwendet werden.
David Foerster

3
in einem Bash - Skript, können Sie verwenden if ((EUID)); then, siehe @ geirha Kommentar
JFS

7
@ Andrew: Variablen werden ersetzt, bevor sie an übergeben werden sudo. Wenn Sie ausführen sudo sh -c 'echo $EUID', werden Sie Ihre erwarteten Ergebnisse sehen.
M. Dudley

6
@Andrew - Ich weiß, ich bin viel zu spät hier, aber für die Nachwelt: $EUIDIst ein Bashismus (wie oben von @DavidFoerster erwähnt), und dein /bin/shist höchstwahrscheinlich ein Link zu /bin/dash, nicht /bin/bash. sudo bash -c 'echo $EUID'wird das erwartete Ergebnis liefern.
Adrian Günter

118

Ein root-Benutzer muss nicht "root" genannt werden. whoamiGibt den ersten Benutzernamen mit der Benutzer-ID zurück 0. $USEREnthält den Namen des angemeldeten Benutzers, der eine Benutzer-ID 0, aber einen anderen Namen haben kann.

Das einzige zuverlässige Programm, mit dem überprüft werden kann, ob das Konto als root angemeldet ist oder nicht:

id -u

Ich benutze -ufür die effektive Benutzer-ID, nicht -rfür die echte Benutzer-ID. Berechtigungen werden bestimmt durch den effektiven Benutzer - ID, nicht die realen ein.

Tests

/etc/passwdenthält die folgenden Benutzernamen mit der Benutzer-ID 0in der angegebenen Reihenfolge:

rootx
root2

Angemeldet als root2, gibt die nächsten Ergebnisse:

  • whoami: rootx
  • echo $USER: root2(Dies gibt eine leere Zeichenkette zurück, wenn das Programm in einer leeren Umgebung gestartet wurde, zB env -i sh -c 'echo $USER')
  • id -u: 0 Wie Sie sehen können, sind die anderen Programme bei dieser Prüfung gescheitert, nur id -ubestanden.

Das aktualisierte Skript würde folgendermaßen aussehen:

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

5
Sie brauchen nicht id -uin bash askubuntu.com/questions/30148/…
jfs

5
Ich versuche immer, so POSIX-konform wie möglich zu bleiben, indem ich sh( dash) anstelle von als Interpreter verwende bash. Aber guter Schuss, spart eine andere Gabel :)
Lekensteyn

Nachdem ich eine Weile kalt war, kam ich zurück und schaute mich um. Lekensteyns Methode scheint in der Tat besser zu sein. Seine Antwort ist jetzt die neu akzeptierte Antwort. +1 an Sie, Lekensteyn, esp. für das schwer zu bekommene Abzeichen von dieser Frage;)
Thomas Ward

Vielen Dank, dass Sie so lange gewartet haben, bis Sie meine Frage beantwortet haben: DI hat ein goldenes Populistenabzeichen und eine bronzene Antwort erhalten.
Lekensteyn

3
Ich habe kürzere Versionen gesehen [ -w / ]. Die Idee bleibt gleich. Hinweis: In bestimmten Chroots schlägt dies [ -w /etc/shadow ]fehl, da dies /etc/shadownicht vorhanden ist. Daher wird der Ansatz mit /bevorzugt. Besser wäre es, den tatsächlichen Bedarf an Root-Berechtigungen zu prüfen. Wenn das Skript schreiben muss /etc/someconfig, überprüfen Sie einfach, ob diese Datei beschreibbar ist, ODER ob die Datei nicht vorhanden und /etcbeschreibbar ist.
Lekensteyn

30

Wie @Lekensteyn sagte , sollten Sie eine effektive Benutzer-ID verwenden. Sie müssen nicht id -ubash anrufen :

#!/bin/bash

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

@ geirhas Vorschlag aus den Kommentaren verwendet eine arithmetische Auswertung:

#!/bin/bash

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

7
Im Allgemeinen sollte man ((..))zum Testen von Zahlen und [[..]]zum Testen von Zeichenfolgen und Dateien verwenden, also würde ich es if (( EUID != 0 )); thenstattdessen tun , oder einfachif ((EUID)); then
geirha

@geirha: Ich habe deinen Vorschlag hinzugefügt.
jfs

2
EUIDsollte werden $EUID. Anstelle der Verwendung von (( $EUID != 0 ))verwenden [ $EUID != 0 ]. Es wird auch funktionieren dash.
Lekensteyn

2
@Lekensteyn: EUIDfunktioniert gut. Die Frage ist bashnicht markiert dash. Der Befehl env -i sh -c '[ $EUID != 0 ]'schlägt fehl, env -i bash -c '(( EUID != 0 ))'funktioniert aber . Übrigens, dashfunktioniert nicht bei einigen Nicht-ASCII-Zeichen unter Ubuntu stackoverflow.com/questions/5160125/… Es ist 2011 und es gibt Leute, die andere Sprachen verwenden.
jfs

Nachdem ich auf dieses Thema zurückgeblickt habe, während ich mich schrecklich gelangweilt und getestet habe, werde ich die hier aufgeführte Methode mit dem $EUIDMaterial von diesem Punkt an anwenden. Ich habe die akzeptierte Antwort daraufhin geändert.
Thomas Ward

20

Dies erreichen Sie mit dem whoamiBefehl, der den aktuellen Benutzer zurückgibt:

#!/bin/bash

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

...

You must be root to do this.Wenn der aktuelle Benutzer dies nicht tut, wird der obige Befehl gedruckt root.


Hinweis: In einigen Fällen können Sie auch einfach die $USERVariable überprüfen :

if [ $USER != 'root' ]

Ich werde einen Blick auf den Code werfen, um zu sehen, ob das Skript dadurch nicht fehlschlägt oder so. Wenn es funktioniert, akzeptiere ich deine Antwort :)
Thomas Ward

4
@ George Edison: Ich empfehle gegen die Verwendung $USER, vor allem auf diese Weise. $USERwird von der Login-Shell gesetzt, es ist keine Weitergabe an das Programm ( env -i sh -c 'echo $USER') erforderlich . Auf diese Weise $USERist leer und es tritt ein Syntaxfehler auf.
Lekensteyn

1
@Lekensteyn Wird nicht nur $USERvon der Shell festgelegt, sondern ist auch leicht zu fälschen. Whoami gibt den tatsächlichen Benutzer zurück.
Paul de Vrieze

2
@PauldeVrieze Was bringt es, diese Prüfung zu täuschen?
htorque

1
@andrewsomething: Wird $USERvon Ihrer Shell interpretiert, sollte Ihr Beispiel sudo sh -c 'echo $USER'sinnvoll sein. @ George: Es wird die falsche Annahme gemacht, dass whoamiimmer rootfür UID 0 zurückgegeben wird.
sam hocevar

11

Unter Berücksichtigung der Effizienz können Sie zuerst die EUIDUmgebungsvariable testen und dann, falls sie nicht vorhanden ist, den Standardbefehl aufrufen id:

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

Auf diese Weise vermeiden Sie aufgrund der ODER-Verknüpfung , dass Sie einen Systembefehl aufrufen und der Abfrage einer speicherinternen Variablen Priorität einräumen.

Wiederverwendung von Code:

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

Ich fürchte, Sie haben es nicht verglichen, nun ja, und das dauert genauso lange wie id -u. Sehen Sie sich die Bank Skript zusammen mit den Ergebnissen darunter hier: pastebin.com/srC3LWQy
LinuxSecurityFreak


2

Eine einfache Möglichkeit, das Skript nur für root ausführbar zu machen, besteht darin, das Skript mit der folgenden Zeile zu starten:
#!/bin/su root


1
Mach das nicht. Es wird versucht, sich direkt als root anzumelden, während sudo auf vielen Systemen erforderlich sein kann, da ersteres verboten ist. Darüber hinaus soll der shebang sicherstellen, dass Ihr Skript in dem Skript ausgeführt wird, für das es entworfen wurde, wohingegen Ihre Methode bewirkt, dass das Skript in der Standardshell von root ausgeführt wird, was nicht vorhergesagt werden kann, wenn das Skript von einem anderen Benutzer als dem Autor ausgeführt wird. Wenn Sie die Berechtigungen eines Skripts mit shebang erhöhen, wird die Portabilität des Skripts erheblich beeinträchtigt und auf vielen Systemen treten Fehler auf. (su: Authentifizierungsfehler)
StarCrashr


1

Dieses Snippet würde:

  • Überprüfen Sie die verschiedenen Sitzungen
  • empfehlen zu verwenden sudo !!
  • und einen Fehler zurückgeben
if ["$ (whoami & 2> / dev / null)"! = "root"] && ["$ (id -un & 2> / dev / null)"! = "root"]
      dann
      echo "Sie müssen root sein, um dieses Skript ausführen zu können!"
      echo "benutze 'sudo !!'"
      Ausfahrt 1
fi

1

Diese Antwort dient nur zum Speichern einer Idee und kann für einige von Ihnen hilfreich sein. Wenn Sie ein Skript benötigen, das von der Desktop-GUI ausgeführt wird und Root-Rechte erfordert, gehen Sie folgendermaßen vor:

#!/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

Auf diese Weise erhalten Sie ein nettes Dialogfenster, in dem Sie nach dem Kennwort des Root-Benutzers gefragt werden. Genau wie bei Kommandozeilen-Sudo.

Das ist gksudomöglicherweise nicht in Ihrem System verfügbar, dann installieren Sie es mit sudo apt-get install gksu.


0

Dieser Code funktioniert sowohl unter Bash als auch unter Stock Bourne sh (getestet unter FreeBSD), das keine EUID definiert. Wenn die EUID existiert, wird ihr Wert zurückgegeben, andernfalls wird der Befehl 'id' ausgeführt. Es ist ein bisschen kürzer als das obige "oder" Beispiel, da es eine eingebaute Shell ": -" verwendet.

Wurzel in sh:

# echo $EUID

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

In bash:
[chaapala@tenfwd2 ese]$ euid=${EUID:-`id -u`}
[chaapala@tenfwd2 ese]$ echo $euid
10260
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.