Wie komme ich nach Hause?

41

Ich habe eine USERVariable in meinem Skript, und ich möchte seinen HOMEPfad basierend auf der USERVariablen sehen. Wie kann ich das machen?

MatthewRock
quelle

Antworten:

72

Es gibt ein Dienstprogramm, mit dem Benutzerinformationen unabhängig davon gesucht werden, ob diese Informationen in lokalen Dateien wie /etc/passwdoder in LDAP oder einer anderen Methode gespeichert sind . Es heißt getent.

Um Benutzerinformationen daraus zu erhalten, führen Sie aus getent passwd $USER. Sie erhalten eine Zeile zurück, die wie folgt aussieht:

[jenny@sameen ~]$ getent passwd jenny
jenny:*:1001:1001:Jenny Dybedahl:/home/jenny:/usr/local/bin/bash

Jetzt können Sie einfach das Ausgangsverzeichnis daraus ausschneiden, z. B. mit cut, wie folgt:

[jenny@sameen ~]$ getent passwd jenny | cut -d: -f6
/home/jenny
Jenny D
quelle
getent ist die bessere Antwort, insbesondere für entfernte Benutzer. in einfacheren Systemen sollte ~ user ausreichen. Hat dich fertig gemacht.
Rui F Ribeiro
@RuiFRibeiro können Sie nicht ~foomit Variablen in verwenden bash. Jedenfalls nicht direkt.
muru
1
@muru - das stimmt - und ist spezifiziertes Verhalten. Das ~scheint sich jedoch zu erweitern, und ein anderes angegebenes Verhalten des Tilde-Präfixes soll durch einen Pfadnamen des anfänglichen Arbeitsverzeichnisses ersetzt werden, das mit dem Anmeldenamen verknüpft ist, der mit der getpwnam()Funktion erhalten wurde, und daher ist die Suche wahrscheinlich ziemlich gut. ich mag allerdings keine tab-erweiterungen - ich tippe gerne tabs.
mikeserv
1
Beachten Sie, dass Sie auf diese Weise nur den Anfangswert von $ HOME erhalten. Die Anmeldeskripte des Benutzers sind vollkommen berechtigt, sie in etwas anderes zu ändern. Das ist ungewöhnlich, aber ich kann mir Situationen vorstellen, in denen es sinnvoll wäre, z. B. zwischen einem lokalen und einem NFS-gemounteten Homedir zu wählen.
zwol
1
@HagenvonEitzen Doppelpunkte sind verboten, gerade weil sie zum Trennen von Feldern verwendet wurden.
Jenny D
9

Mit können Sie das Basisverzeichnis evaleiner Person abrufen.

eval echo "~$USER"

Zumindest für lokale Benutzer funktioniert dies auf jeden Fall. Ich weiß nicht, ob Remote-Benutzer wie LDAP damit umgehen eval.

Sarolf.Thorleif
quelle
1
Keine Notwendigkeit, dort auszuwerten. Sei vorsichtig mit deinem Englisch.
Rui F Ribeiro
4
@nwk an evalwird benötigt. Bash wird ~foonach variabler Erweiterung nicht verarbeitet .
muru
1
Interessant, danke, dies bekommt jedoch nur das Verzeichnis des aktuellen Benutzers, nicht von anderen Benutzern. Ich denke, LDAP-Benutzer werden nicht behandelt, obwohl ich mich irren kann.
Rui F Ribeiro
3
@RuiFRibeiro Mit LDAP funktioniert es einwandfrei. Verwenden Sie stattdessen nur die Variable, die den Benutzernamen Ihres LDAP-Benutzers enthält USER.
muru
3
Verwenden Sie diese nicht ohne dass die Überprüfung $USERdehnt sich auf nur eine einzige Kette von Buchstaben.
Chepner
4

Der übliche Ort ist /home/$USER, aber das muss nicht universell sein. Der endgültige Ort für die Suche nach solchen Informationen befindet sich in der Datei /etc/passwd.

Diese Datei ist weltweit lesbar (jeder kann sie lesen), sodass jeder Benutzer Zugriff auf ihren Inhalt hat.
Wenn $ USER in der Datei vorhanden ist, ist der vorletzte Eintrag das Benutzerverzeichnis HOME.

Dadurch wird der Eintrag ausgewählt und das HOME-Verzeichnis gedruckt:

awk -v FS=':' -v user="$USER" '($1==user) {print $6}' "/etc/passwd"

Bei komplexeren (entfernten) Systemen ist getent der übliche Befehl, um Benutzerinformationen vom NSS-System (Name Service Switch Libraries) abzurufen.

Ein Befehl von

echo $(getent passwd $USER )| cut -d : -f 6

Liefert gleichwertige Informationen (falls verfügbar).


quelle
2
Sie haben ~ user dafür, und Ihre Lösung berücksichtigt keine Benutzer in komplexeren Systemen, wie z. B. Benutzer, die aus LDAP stammen, wo Sie getent verwenden müssen.
Rui F Ribeiro
2

Wenn der Benutzer nicht existiert, getentwird ein Fehler zurückgegeben.

Hier ist eine kleine Shell-Funktion, die den Exit-Code von nicht ignoriert getent:

get_home() {
  local result; result="$(getent passwd "$1")" || return
  echo $result | cut -d : -f 6
}

Hier ist ein Anwendungsbeispiel:

da_home="$(get_home missing_user)" || {
  echo 'User does NOT exist!'; exit 1
}

# Now do something with $da_home
echo "Home directory is: '$da_home'"
Elifarley
quelle
1

Wenn Sie als root angemeldet sind, USERdas Kennwort kennen oder USERkein Kennwort haben, ist Folgendes eine weitere Option:

    su -c 'echo ~' ${USER}

suWenn das Standardverhalten USERundefiniert oder leer ist, suwird versucht, den Befehl als root auszuführen.

Wenn der Wert USERkein gültiger Benutzername ist, dann wird ein entsprechender Fehler ausgelöst werden: su: user <user> does not exist.

Hier gibt es bereits viele gute Antworten, aber dies kann trotzdem jemandem helfen.

monotonee
quelle
Dies ist abhängig von der Systemkonfiguration nicht sicher. Es wird ein Prozess (die Shell, die Echo ausführt) als dieser Benutzer ausgeführt, sodass der Benutzer (zum Beispiel) die Shell verfolgen und Ihnen eine beliebige Ausgabe geben kann. Es wird auch im Setup des Benutzers ausgeführt, sodass es möglich ist, dass die Shell-Konfigurationsdateien des Benutzers ausgeführt werden (was auch zu beliebigen Ausgaben führen kann). Oder die Umgebung wird über pam geladen. Oder machen Sie einfach so etwas wie SIGSTOP, damit es ewig dauert und DOS Ihr Skript effektiv angreift.
Derobert