437 Stimmen

Wie man in einem Bash-Skript überprüft, ob man als Root läuft

Ich schreibe ein Skript, das Root-Berechtigungen erfordert, und ich möchte es so machen, dass es einfach "Bitte als Root ausführen" ausgibt und beendet, wenn das Skript nicht als Root ausgeführt wird.

Hier ist etwas Pseudocode für das, was ich suche:

if (whoami != root)
  then echo "Bitte als Root ausführen"

  else (Aktionen ausführen)
fi

exit

Wie könnte ich das am besten (sauber und sicher) umsetzen? Vielen Dank!

Ach, um es klarzustellen: Der Teil (Aktionen ausführen) würde das Ausführen von Befehlen erfordern, die selbst Root-Rechte benötigen. Das Ausführen als normaler Benutzer würde also einfach einen Fehler verursachen. Dies soll nur dazu dienen, ein Skript sauber auszuführen, das Root-Befehle erfordert, ohne sudo im Skript zu verwenden. Ich suche nur etwas syntaktischen Zucker.

620voto

ptierno Punkte 9544

Die $EUID Umgebungsvariable enthält die aktuelle Benutzer-ID. Die UID von Root ist 0. Verwenden Sie etwas Ähnliches in Ihrem Skript:

if [ "$EUID" -ne 0 ]
  then echo "Bitte als Root ausführen"
  exit
fi

Hinweis: Wenn Sie 2: [: Ungültige Nummer: erhalten, überprüfen Sie, ob Sie #!/bin/sh oben haben und ändern Sie es in #!/bin/bash.

177voto

Nathan Punkte 69934

Einige Antworten wurden gegeben, aber es scheint, dass die beste Methode ist zu verwenden ist:

  • id -u
  • Wenn es als Root ausgeführt wird, liefert es eine ID von 0 zurück.

Dies scheint zuverlässiger zu sein als die anderen Methoden und es scheint, dass es auch dann eine ID von 0 zurückgibt, wenn das Skript über sudo ausgeführt wird.

101voto

sberder Punkte 4265

In einem Bash-Skript gibt es mehrere Möglichkeiten zu überprüfen, ob der aktuelle Benutzer root ist.

Als Warnung: Überprüfen Sie nicht, ob ein Benutzer root ist, indem Sie den Benutzernamen root verwenden. Nichts garantiert, dass der Benutzer mit der ID 0 tatsächlich root heißt. Es handelt sich um eine weit verbreitete Konvention, der jedoch jederzeit jemand den Superuser umbenennen könnte.

Meiner Meinung nach ist der beste Weg bei der Verwendung von bash, $EUID zu verwenden, wie es in der Manpage steht:

EUID   Erweitert zur effektiven Benutzer-ID des aktuellen Benutzers, die beim Start der Shell initialisiert wird. Diese Variable ist schreibgeschützt.

Dies ist besser als $UID, das geändert werden könnte und nicht den tatsächlichen Benutzer widerspiegelt, der das Skript ausführt.

if (( $EUID != 0 )); then
    echo "Bitte als Root ausführen"
    exit
fi

Ein Weg, wie ich dieses Problem angehe, ist das Einbinden von sudo in meine Befehle, wenn sie nicht als Root ausgeführt werden. Hier ist ein Beispiel:

SUDO=''
if (( $EUID != 0 )); then
    SUDO='sudo'
fi
$SUDO ein_befehl

So wird mein Befehl als Root ausgeführt, wenn der Superuser verwendet wird, oder als sudo, wenn er von einem normalen Benutzer ausgeführt wird.

Wenn Ihr Skript immer als Root ausgeführt werden soll, setzen Sie einfach die Rechte entsprechend (0500).

97voto

Dale_Reagan Punkte 1923

Meine Einzeiler:

if [ "$(id -u)" -ne 0 ]; then echo "Bitte als root ausführen." >&2; exit 1; fi

47voto

LinuxSecurityFreak Punkte 2308

In dieser Antwort sei klar, dass ich davon ausgehe, dass der Leser den Unterschied zwischen modernen Shells wie bash, zsh und anderen im Vergleich zu portablen POSIX-Shells wie dash versteht.

Ich glaube, hier gibt es nicht viel zu erklären, da die hoch bewerteten Antworten bereits einen guten Job gemacht haben, vieles zu erklären.

Sollte jedoch noch etwas weiter zu erklären sein, zögern Sie nicht, einen Kommentar abzugeben, ich werde mein Bestes tun, um die Lücken zu füllen.


Optimierte Allround-Lösung für Leistung und Zuverlässigkeit; mit allen Shells kompatibel

Neue Lösung:

# Funktion zum Testen, ob der Benutzer Root ist oder nicht
is_user_root () { [ "${EUID:-$(id -u)}" -eq 0 ]; }

Benchmark (Speichern in Datei is_user_root__benchmark)

#+------------------------------------------------------------------------------+
#|                           is_user_root() Benchmark                           |
#|                  "Bash ist schnell, während Dash hier langsam ist"            |
#|                          Sprache: POSIX-Shellskript                          |
#|                     Urheberrecht: 2020-2021 Vlastimil Burian                   |
#|                      E-Mail: info[..]vlastimilburian[..]cz                     |
#|                               Lizenz: GPL 3.0                               |
#|                                 Version: 1.2                                 |
#+------------------------------------------------------------------------------+

readonly iterations=10000

# Absichtlich hat die Datei kein Ausführungsbit und keinen Shebang
# Um sie zu verwenden, rufen Sie die Datei direkt mit Ihrem Shell-Interpreter auf, z. B.:

# bash is_user_root__benchmark    ## sollte einen Bruchteil einer Sekunde dauern
# dash is_user_root__benchmark    ## könnte etwa 10 Sekunden dauern

is_user_root () { [ "${EUID:-$(id -u)}" -eq 0 ]; }

print_time   () { date +"%T.%2N"; }
print_start  () { printf '%s' 'Start  : '; print_time; }
print_finish () { printf '%s' 'Finish : '; print_time; }

printf '%s\n' '___is_user_root()___'; print_start

i=1; while [ "$i" -lt "$iterations" ]; do
    is_user_root
    i=$((i+1))
done; print_finish

Beispiele für die Verwendung und Dauer:

$ dash is_user_root__benchmark 
___is_user_root()___
Start  : 03:14:04.81
Finish : 03:14:13.29

$ bash is_user_root__benchmark 
___is_user_root()___
Start  : 03:16:22.90
Finish : 03:16:23.08

Erklärung

Da es vielfach schneller ist, die $EUID Standard-bash-Variable zu lesen, die effektive Benutzer-ID-Nummer, als den Befehl id -u POSIX-konform auszuführen, um die Benutzer-ID zu finden, kombiniert diese Lösung beide in eine schön verpackte Funktion. Wenn, und nur wenn, das $EUID aus irgendeinem Grund nicht verfügbar ist, wird der Befehl id -u ausgeführt, um sicherzustellen, dass wir den richtigen Rückgabewert erhalten, unabhängig von den Umständen.


Warum ich diese Lösung poste, nachdem der OP vor so vielen Jahren gefragt hat

Nun, wenn ich richtig sehe, scheint oben ein fehlendes Code-Stück zu sein.

Sie sehen, es gibt viele Variablen, die berücksichtigt werden müssen, und eine davon ist die Kombination von Leistung und Zuverlässigkeit.


Tragbare reine POSIX-Lösung + Beispiel für die Verwendung der oben genannten Funktion

#!/bin/sh

# Funktion zum Testen, ob der Benutzer Root ist oder nicht (nur POSIX)
is_user_root ()
{
    [ "$(id -u)" -eq 0 ]
}

if is_user_root; then
    echo 'Du bist der allmächtige Root!'
    # Du kannst alles tun, was du brauchst...
else
    echo 'Du bist nur ein gewöhnlicher Benutzer.' >&2
    exit 1
fi

Schlussfolgerung

So sehr Sie es vielleicht nicht mögen, die Unix/Linux-Umgebung hat sich stark diversifiziert. Das bedeutet, dass es Menschen gibt, die bash, zsh und andere moderne Shells so sehr mögen, dass sie nicht einmal an Portabilität (POSIX) denken. Heutzutage ist es eine Frage der persönlichen Wahl und Bedürfnisse.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X