Beispiel zur Identifizierung des Benutzers mithilfe eines Linux-Bash-Skripts

Beispiel zur Identifizierung des Benutzers mithilfe eines Linux-Bash-Skripts

In Bash-Skripten oder direkt im Skript selbst ist es häufig erforderlich, Befehle mit „sudo“ auszuführen. Dies wirft jedoch eine Reihe von Problemen auf.

Sollte beispielsweise bei der Verwendung von sudo die Variable ~ oder $HOME im Skript, die auf den Benutzerordner verweist, auf meinen realen Benutzerordner wie /home/pi oder auf den Benutzerordner /root/? des Superadministrators verweisen?

Es verweist tatsächlich auf den Ordner /root/, was wir auf keinen Fall wollen. Für viele Befehle, beispielsweise zum Installieren eines Programms, ist jedoch die Verwendung von sudo erforderlich. Was soll ich also tun?

Lassen Sie mich zunächst meine Erfahrungen mit Ihnen teilen: Die Ausführung von Befehlszeilenberechtigungen kann aus Leistungssicht in die folgenden fünf Situationen unterteilt werden:

  • Admin-Handbuch: Normale Benutzer geben Befehle manuell ein
  • sudo-manual: Geben Sie den Befehl plus sudo manuell ein
  • admin-bash: Bash-Skripte als normaler Benutzer ausführen
  • sudo-bash: Bash-Skripte mit sudo ausführen
  • root-any: Melden Sie sich als Root-Benutzer an

In diesen 4 Situationen werden viele Variablen und Umgebungsvariablen oft verwechselt! (Das Chaos bezieht sich auf uns, nicht auf den Computer)

Und hier noch ein kleiner Tipp:

Wir alle wissen, dass die Variable ~ auf das Verzeichnis des aktuellen Benutzers verweist. Tatsächlich kann eine Variable im Format ~abc auf das Benutzerverzeichnis eines bestimmten Benutzers verweisen, so wie ~pi auf /home/pi oder ~ubuntu auf /home/ubuntu verweist.

Lassen Sie uns unsere Gedanken klären:

Bei der normalen Ausführung von Skripten wie ./test.sh treten keine Probleme auf. Auch wenn sudo im Skript vorkommt, wie beispielsweise sudo apt-get update, treten keine Probleme auf.
Mit anderen Worten: Ernsthafte Probleme treten nur dann auf, wenn „sudo“ für das gesamte Skript ausgeführt wird, z. B. „sudo ./test.sh!“

Angenommen, mein tatsächlicher Benutzer ist pi und mein HOME-Verzeichnis ist /home/pi. Jetzt möchte ich die richtige Lösung im Ausführungsmodus von sudo ./test.sh finden.
Nachfolgend sind die verschiedenen Anweisungen und Variablen im Skript und die angezeigten Ergebnisse aufgeführt:

# (Nicht empfohlen!)
$ wer ich bin
>>> Wurzel

# Anders als whoami kann es anzeigen, welche Benutzer derzeit am Computer angemeldet sind, einschließlich aller lokal und über ssh angemeldeten Benutzer. $ who am i
>>> Einige Maschinen zeigen leer an >>> Mac zeigt: pi ttys001 Nov 26 16:57

# Entspricht whoami (nicht empfohlen!)
$ echo $USER
>>> Wurzel

# Speicherort des Benutzer-Home-Verzeichnisses (nicht zuverlässig und nicht empfohlen!)
echo $HOME
>>> /Wurzel

$ Speicherort des Benutzer-Home-Verzeichnisses, entspricht $HOME (nicht empfohlen!)
$ echo ~
>>> /Wurzel

# Verwenden Sie die Umgebungsvariable LOGNAME direkt
$ echo $LOGNAME
>>> Wurzel

# Rufen Sie die Umgebungsvariable LOGNAME explizit auf 
$ printenv LOGNAME
>>> Wurzel


# SUDO_USER ist eine Umgebungsvariable in der ENV des Root-Benutzers.
# Gleichzeitig haben normale Benutzer keine Umgebung, nur Root-Benutzer können sie anzeigen $ sudo echo $SUDO_USER
>>> pi


# Aufrufumgebungsvariable SUDO_USER anzeigen (nicht empfohlen!)
# Anhand der Ergebnisse können Sie erkennen, dass es anders ist, wenn sudo zum Skript hinzugefügt wird, auch wenn das Skript als sudo ausgeführt wird!
$ printenv SUDO_USER
>>> pi
$ sudo printenv SUDO_USER
>>> Wurzel

Aus dem obigen Test können wir ersehen, dass viele Variablen „unzuverlässig“ sind, wenn wir sudo zum Ausführen des Bash-Skripts verwenden.

In Stackoverflow besteht die konsistentere Tendenz darin, die Umgebungsvariable $SUDO_USER zu verwenden. Und im Test ist es tatsächlich das „stabilste“, das heißt, es kann unter verschiedenen Berechtigungen und Betriebssystemen konsistent sein (nur für Systeme mit sudo).

Da wir nun den Benutzernamen haben, können wir einen Befehl wie ~pi verwenden, um das Home-Verzeichnis /home/pi abzurufen, aber!

Nun tritt das Problem erneut auf: Beim manuellen Eintippen erhalten wir zwar die korrekte Adresse von ~pi, das Skript erkennt jedoch nicht, was ~pi ist. Es handelt sich höchstens um einen String, nicht um eine Variable.

In diesem Fall können wir nicht die ~abc-Methode verwenden, sondern müssen die altmodische, aber definitiv nicht verwirrende Methode verwenden:
Schauen Sie direkt in /etc/passwd nach.

Manuell können Sie passwd direkt öffnen, um es anzuzeigen, aber im Skript ist es problematischer. Am bequemsten ist es, den Systembefehl getent (Befehl „Get Entries“) zu verwenden, um die Informationen des angegebenen Benutzers abzurufen:

$ getent passwd pi
>>> pi:x:1000:1000:,,,:/home/pi:/bin/bash

Also müssen wir nur noch /home/pi herausnehmen, was wir mit „cut“ ganz einfach tun können.

Der gesamte Vorgang läuft also wie folgt ab:

ich=$SUDO_USER
myhome=`getent passwd $me | cut -d: -f 6`

/home/pi erfolgreich erhalten!

Gehen wir einen Schritt weiter: Was passiert, wenn das Skript nicht als sudo ausgeführt wird? Derzeit gibt es in den Umgebungsvariablen des Root-Benutzers und der normalen Benutzer keine SUDO_USER-Variable. Dann müssen wir einen Beurteilungsschritt hinzufügen:

ich=${SUDO_USER:-$LOGNAME}
myhome=`getent passwd $me | cut -d: -f 6`

Das heißt, wenn SUDO_USER leer ist, wird normalerweise $LOGNAME verwendet, um den aktuellen Benutzer abzurufen. Warum nicht $LOGNAME statt $USER verwenden? Weil USER nicht auf jedem System verfügbar ist, LOGNAME jedoch auf allen *nix-Systemen verfügbar ist.

erneuern

Da einige Betriebssysteme LOGNAME nicht korrekt abrufen können, wird die uid-Methode verwendet, um den Benutzerpfad abzurufen:

HOUSE=`getent passwd ${SUDO_UID:-$(id -u)} | cut -d: -f 6`

Erneut aktualisieren

MacOS hat kein /etc/passwd und unterstützt die Methode getent passwd <UID> zum Abrufen von Benutzerinformationen nicht, aber der Inhalt der Variablen $USER und $HOME kann unter sudo unverändert bleiben.

Ändern Sie es also wie folgt:

HAUS=${$(`getent passwd ${SUDO_UID:-$(id -u)} | cut -d: -f 6`):-$HOME}

Das heißt, wenn die GetEnt-Methode den Inhalt nicht abrufen kann, wird der Wert von $HOME direkt abgerufen.

Erneut aktualisieren

Da Bash den obigen verschachtelten ternären Ausdruck nicht unterstützt, muss er getrennt werden:

HOUSE="`cat /etc/passwd |grep ${SUDO_UID:-$(id -u)} | cut -d: -f 6`"
HAUS=${HAUS:-$HOME}

Immer wieder aktualisieren

Wenn es sich um Root handelt, gleicht grep uid alle Zeilen ab, die 0 in passwd enthalten. Es sollte also wie folgt verbessert werden:

HOUSE="`cat /etc/passwd |grep ^${SUDO_USER:-$(id -un)}: | cut -d: -f 6`"
HAUS=${HAUS:-$HOME}

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Starten Sie mithilfe eines Batch-Skripts ein Git-Bash-Fenster in einem bestimmten Verzeichnis
  • Detaillierte Erklärung des Skript-Debugging-Mechanismus in Bash
  • Umgang mit Variablen mit Leerzeichen in Shell-Skripten (Bash-Skripten)
  • Mit dem Bash-Skript können Sie bei jeder Anmeldung an der Shell Linux-Systeminformationen anzeigen
  • So überwachen Sie die Linux-Speichernutzung mit einem Bash-Skript
  • Detaillierte Erklärung, wie man ein Passwort an den SSH/SCP-Befehl im Bash-Skript übergibt
  • Detaillierte Erklärung der Unterschiede zwischen Quelle, sh, bash und ./ bei der Ausführung von Shell-Skripten
  • Überwachung von Linux-Bash-Skripts, Starten und Stoppen des Skriptschreibens für Weblogic-Dienste
  • So schreiben Sie sichere, voll funktionsfähige Bash-Skripte

<<:  Analyse des Quellcodes des React-Ereignismechanismus

>>:  Grafisches Tutorial zur Installation und Konfiguration von mysql5.7.19 winx64 (win10)

Artikel empfehlen

Über das WeChat Mini-Programm zur Implementierung von Cloud-Zahlungen

Inhaltsverzeichnis 1. Einleitung 2. Gedankenanaly...

Implementierung von zwei Basis-Images für die Docker-Bereitstellung von Go

1. golang:neuestes Basis-Image mkdir gotest Berüh...

CentOS7 64-Bit-Installation MySQL Grafik-Tutorial

Voraussetzungen für die Installation von MySQL: I...

Das Homepage-Design spiegelt am besten das Niveau des Webdesigners wider

Bei den vielen Projekten, an denen ich mitgearbei...

Kann CSS auf diese Weise verwendet werden? Die Kunst wunderlicher Farbverläufe

Im vorherigen Artikel – Der Charme einer Zeile CS...

Vollständiges Beispiel einer Vue-Polling-Request-Lösung

Verständnis von Umfragen Tatsächlich liegt der Sc...

So verwenden Sie das VS2022-Remote-Debugging-Tool

Manchmal müssen Sie bei der Arbeit ein Remote-Deb...

10 tödliche semantische Fehler in der Webtypografie

<br />Dies stammt aus dem Inhalt von „Web Fr...

Detaillierte Erklärung der Bind-Mounts für die Docker-Datenspeicherung

Bevor Sie diesen Artikel lesen, hoffe ich, dass S...

Detailliertes Beispiel für die Verwendung von useState in React

Verwendungsstatus useState fügt einer Komponente ...

Vue implementiert Mehrfachauswahl im unteren Popup-Fenster

In diesem Artikelbeispiel wird der spezifische Co...