Должны определять все домашние каталоги пользователей - проблема с тильдой скриптов
Предположим, что у someuser есть домашний каталог /home/someuser
NAME = someuser
В bash - какое выражение я использую, комбинируя тильду (~) и $NAME, чтобы вернуть домашний каталог пользователей?
HOMEDIRECTORY=~someuser
echo $HOMEDIRECTORY
/home/someuser
NAME=someuser
echo ~$NAME
~someuser
любые предложения?
Ответы
Ответ 1
Безопаснее:
eval HOMEDIRECTORY="$(printf "~%q" "$NAME")"
Здесь опция %q
для printf
цитирует и ускользает от опасных символов.
Если $NAME
- joe, вы получите что-то вроде /home/joe
. Для root вы можете получить /root
. Для "abc; rm something" вы получите "~ abc; rm something" вместо того, чтобы что-то удалить.
Ответ 2
Если у вас есть доступ к getent
:
getent passwd "$NAME" | cut -d: -f 6
Ответ 3
Tilde (~) это то же самое, что и $HOME, поэтому не все пользователи будут иметь корневой каталог в одном каталоге.
Но если вы настаиваете на использовании тильды, выполните следующие действия:
echo ~/../$NAME
Смотрите:
$ pwd
/home/oreyes
$ export NAME=john
$ export DIRECTORYNAME=~/../$NAME
$ cd $DIRECTORYNAME
$ pwd
/home/john
Ответ 4
Интересная разница между bash и csh, где ~ $VARNAME фактически делает то, что вы ожидаете!
Это некрасиво, но, похоже, работает в bash:
homedir=`eval "echo ~$USERNAME"`
Теперь $homedir содержит домашний каталог, связанный с $USERNAME.
Ответ 5
ЛУЧШИЙ МЕТОД
Обязательно: ничего
(n.b., это тот же метод, что и getent, не требуя getent)
home() { # returns empty string on invalid user
grep "^$1:" /etc/passwd | cut -d ':' -f 6
}
# grep "^$user:" /etc/passwd | cut -d ':' -f 6
/var/lib/memcached
ЛУЧШИЙ МЕТОД ДЛЯ ЛОТОКА ROOT
Требуется: Linux, root (или sudo)
home() { # returns errorlevel 1 on invalid user
su "$1" -s '/bin/sh' -c 'echo $HOME'
}
# su memcached -s '/bin/sh' -c 'echo $HOME'
/var/lib/memcached
РЕШЕНИЕ ДЛЯ ПОЛНОГО РАСШИРЕНИЯ
magic() { # returns unexpanded tilde express on invalid user
local _safe_path; printf -v _safe_path "%q" "$1"
eval "ln -sf $_safe_path /tmp/realpath.$$"
readlink /tmp/realpath.$$
rm -f /tmp/realpath.$$
}
Пример использования:
$ magic ~nobody/would/look/here
/var/empty/would/look/here
$ magic ~invalid/this/will/not/expand
~invalid/this/will/not/expand
СПОСОБ ЖЕСТКОСТИ CSH
Это BASH script, он просто вызывает csh.
Требуется: csh
home() { # return errorlevel 1 on invalid user
export user=$1; csh -c "echo ~$user"
}
$ export user=root; csh -c "echo ~$user"
/var/root
$ export user=nodfsv; csh -c "echo ~$user"
Unknown user: nodfsv.
МЕТОД ДЕСУЛЯЦИИ
Обязательный параметр: палец (устаревший)
home() {
finger -m "$1" |
grep "^Directory:" |
sed -e 's/^Directory: //' -e 's/ .*//'
}
# finger -m "haldaemon" |
> grep "^Directory:" |
> sed -e 's/^Directory: //' -e 's/ .*//'
/home/haldaemon
Вы можете объединить операцию grep в sed, но поскольку этот метод является сочным, я бы не стал беспокоиться.
Ответ 6
один альтернативный путь
awk -F":" '{print "user: "$1", Home directory is: "$6}' /etc/passwd