Как получить ДОМ, предоставленный ПОЛЬЗОВАТЕЛЕМ?

41

У меня есть USERпеременная в моем скрипте, и я хочу видеть его HOMEпуть на основе USERпеременной. Как я могу это сделать?

MatthewRock
источник

Ответы:

73

Существует утилита, которая ищет информацию пользователя независимо от того, хранится ли эта информация в локальных файлах, таких как /etc/passwdили в LDAP, или каким-либо другим способом. Это называется getent.

Для того, чтобы получить информацию о пользователе, вы запускаете getent passwd $USER. Вы получите строку назад, которая выглядит так:

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

Теперь вы можете просто вырезать из него домашний каталог, например, используя cut, например:

[jenny@sameen ~]$ getent passwd jenny | cut -d: -f6
/home/jenny
Дженни Д
источник
getent - лучший ответ, особенно с удаленным пользователем. в более простых системах ~ пользователя должно быть достаточно. Модедировал тебя.
Руи Ф Рибейро
@RuiFRibeiro, вы не можете использовать ~fooс переменными в bash. Во всяком случае, не напрямую.
Муру
1
@ MURU - это правда, - и это специальное поведение. ~действительно кажется вкладка-расширение, хотя и другой билд поведение тильды-префикс должно быть заменено на имя путем первоначального рабочего каталога , связанный с именем пользователя , полученным с помощью getpwnam()функции и поэтому , вероятно , что поиск очень хорошо. мне не нравятся расширения вкладок, хотя - я люблю печатать вкладки.
mikeserv
1
Обратите внимание, что это только возвращает вам начальное значение $ HOME; Сценарии входа пользователя имеют полное право изменить его на что-то другое. Это необычная вещь, но я могу представить себе ситуации, когда это было бы целесообразно, например, выбор между локальным и смонтированным по NFS homedir.
Звол
1
@HagenvonEitzen Двоеточия запрещены именно потому, что они использовались для разделения полей.
Дженни Д
9

Вы можете использовать, evalчтобы получить чей-то домашний каталог.

eval echo "~$USER"

По крайней мере, для локальных пользователей это работает точно. Я не знаю, обрабатываются ли удаленные пользователи, такие как LDAP eval.

Sarolf.Thorleif
источник
1
Там нет необходимости для eval там. Будьте осторожны с вашим английским.
Руи Ф Рибейро
4
@nwk evalнужен. Bash не обрабатывает ~fooпосле расширения переменной.
Муру
1
Интересно, спасибо, однако это получает только каталог текущего пользователя, а не других пользователей. Я думаю, что пользователи LDAP не обрабатываются, хотя я могу ошибаться.
Руи Ф Рибейро
3
@RuiFRibeiro С LDAP будет работать нормально, просто используйте любую переменную, содержащую имя пользователя вашего LDAP вместо USER.
Муру
3
Не используйте это , не проверив , что $USERрасширяется до всего одной строки алфавитных символов.
Chepner
4

Обычное место есть /home/$USER, но это не обязательно должно быть универсальным. Определенное место для поиска такой информации находится внутри файла /etc/passwd.

Этот файл доступен для чтения всем (любой может его прочитать), поэтому любой пользователь имеет доступ к его содержимому.
Если в файле существует $ USER, запись, предшествующая последней, является пользовательским каталогом HOME.

Это выберет запись и распечатает каталог HOME:

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

В более сложных (удаленных) системах getent - это обычная команда для получения информации о пользователях из системы NSS (библиотеки Service Name Switch).

Команда

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

Предоставит эквивалентную информацию (если имеется).


источник
2
для этого у вас есть пользователь, и ваше решение не предусматривает пользователей в более сложных системах, таких как пользователи из LDAP, где вам нужно использовать getent.
Руи Ф Рибейро
2

Если пользователь не существует, getentвернет ошибку.

Вот небольшая функция оболочки, которая не игнорирует код выхода getent:

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

Вот пример использования:

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
источник
1

Если вы вошли в систему как пользователь root, если вы знаете USERпароль или если у USERнего нет пароля, следующий вариант - еще один вариант:

    su -c 'echo ~' ${USER}

При стандартном suповедении, если USERон не определен или пуст, он suпопытается выполнить команду от имени пользователя root.

Если значение USERне является допустимым именем пользователя, то будет поднят соответствующая ошибка: su: user <user> does not exist.

Здесь уже есть много хороших ответов, но это может кому-то помочь.

monotonee
источник
Это не безопасно, в зависимости от конфигурации системы. Он запускает процесс (оболочка с эхо) от имени этого пользователя, поэтому пользователь может (например) отслеживать трассировку и выдавать произвольный вывод. Он также запускается в настройках пользователя, поэтому возможно, что файлы конфигурации оболочки пользователя запускаются (что также может давать произвольные результаты). Или среда загружается через PAM. И т. Д. Или просто сделайте что-нибудь простое, например, отправьте SIGSTOP, чтобы DOS атаковал ваш сценарий навсегда.
Дероберт