Jak uzyskać HOME, biorąc pod uwagę UŻYTKOWNIKA?

41

Mam USERzmienną w swoim skrypcie i chcę zobaczyć jego HOMEścieżkę na podstawie tej USERzmiennej. Jak mogę to zrobić?

MatthewRock
źródło

Odpowiedzi:

72

Istnieje narzędzie, które wyszukuje informacje o użytkowniku niezależnie od tego, czy są one przechowywane w lokalnych plikach, takich jak /etc/passwdLDAP, czy w innej metodzie. To się nazywa getent.

Aby uzyskać z niego informacje o użytkowniku, uruchamiasz getent passwd $USER. Otrzymasz linię, która wygląda następująco:

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

Teraz możesz po prostu wyciąć z niego katalog domowy, np. Używając cut, tak:

[jenny@sameen ~]$ getent passwd jenny | cut -d: -f6
/home/jenny
Jenny D.
źródło
getent to lepsza odpowiedź, szczególnie dla użytkownika zdalnego. w prostszych systemach ~ użytkownik powinien wystarczyć. Zmodyfikowałem cię.
Rui F Ribeiro,
@RuiFRibeiro, którego nie można używać ~fooze zmiennymi w bash. W każdym razie nie bezpośrednio.
muru,
1
@muru - to prawda - i jest to określone zachowanie. ~wydaje się kartę rozwinąć, choć i inny spec''d zachowanie przedrostkiem tyldy zostaje zastąpiony przez ścieżkę początkowego katalogu roboczego związanego z nazwą logowania uzyskanych przy użyciu getpwnam()funkcji i tak pewnie, że wyszukiwanie jest całkiem dobry. Jednak nie lubię rozszerzeń tabulatorów - lubię pisać tabulatory.
mikeserv
1
Zauważ, że to daje ci tylko wartość początkową $ HOME; skrypty logowania użytkownika mają pełne prawo do zmiany go na coś innego. Jest to niezwykła rzecz do zrobienia, ale mogę myśleć o sytuacjach, w których byłoby to rozsądne, np. Wybierając między lokalnym a montowanym na NFS homedire.
zwolnienie
1
@HagenvonEitzen Dwukropki są zabronione właśnie dlatego, że zostały użyte do oddzielenia pól.
Jenny D,
9

Możesz użyć, evalaby uzyskać czyjś katalog domowy.

eval echo "~$USER"

To działa na pewno przynajmniej dla lokalnych użytkowników. Nie wiem, czy zdalni użytkownicy, tacy jak LDAP, są obsługiwani eval.

Sarolf.Thorleif
źródło
1
Nie ma potrzeby ewaluacji. Uważaj na swój angielski.
Rui F Ribeiro,
4
@ nwk evaljest potrzebne. Bash nie przetwarza ~foopo rozwinięciu zmiennej.
muru,
1
Ciekawe, dzięki, ale dostaje to tylko katalog bieżącego użytkownika, a nie innych użytkowników. Myślę, że użytkownicy LDAP nie są obsługiwani, chociaż mogę się mylić.
Rui F Ribeiro,
3
@RuiFRibeiro Będzie działać dobrze z LDAP, wystarczy użyć dowolnej zmiennej zawierającej nazwę użytkownika użytkownika LDAP zamiast USER.
muru,
3
Nie używaj tego bez sprawdzenia, czy $USERrozwija się do zaledwie jednym ciągiem znaków alfabetycznych.
chepner,
4

Zwykle jest to miejsce /home/$USER, ale to nie musi być uniwersalne. Ostateczne miejsce wyszukiwania takich informacji znajduje się w pliku /etc/passwd.

Ten plik jest czytelny na całym świecie (każdy może go przeczytać), więc każdy użytkownik ma dostęp do jego zawartości.
Jeśli w pliku istnieje US $, pozycja poprzedzająca przedostatnia to katalog HOME użytkownika.

Spowoduje to wybranie wpisu i wydrukowanie katalogu HOME:

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

W przypadku bardziej złożonych (zdalnych) systemów getent jest zwykłą komendą do uzyskiwania informacji o użytkownikach z systemu NSS (bibliotek usług przełączania nazw).

Polecenie

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

Dostarczy równoważne informacje (jeśli są dostępne).


źródło
2
masz ~ użytkownika do tego, a twoje rozwiązanie nie uwzględnia użytkowników w bardziej złożonych systemach, takich jak użytkownik pochodzący z LDAP, gdzie musisz użyć getent.
Rui F Ribeiro,
2

Jeśli użytkownik nie istnieje, getentzwróci błąd.

Oto mała funkcja powłoki, która nie ignoruje kodu wyjścia getent:

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

Oto przykład użycia:

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
źródło
1

Jeśli jesteś zalogowany jako root, znasz USERhasło lub jeśli USERnie ma hasła, następująca opcja jest następująca:

    su -c 'echo ~' ${USER}

W przypadku standardowego suzachowania, jeśli USERjest niezdefiniowany lub pusty, wówczas suspróbuje uruchomić polecenie jako root.

Jeśli wartość USERnie jest prawidłowa nazwa użytkownika, a następnie odpowiedni błąd zostanie podniesiona: su: user <user> does not exist.

Jest tu już wiele dobrych odpowiedzi, ale to może komuś pomóc.

monotonia
źródło
To nie jest bezpieczne, w zależności od konfiguracji systemu. Uruchamia proces (echo powłoki) jako ten użytkownik, więc użytkownik może (na przykład) śledzić powłokę i dawać dowolne dane wyjściowe. Działa również w konfiguracji użytkownika, więc możliwe jest, że pliki konfiguracyjne powłoki użytkownika są uruchamiane (co może również dawać dowolne wyniki). Lub ładuje środowisko przez pam. Itd. Lub po prostu zrób coś tak prostego, jak wysłanie SIGSTOP, aby działało to wiecznie, skutecznie DOS atakując twój skrypt.
derobert