cd ~ <user> возможен, но почему мы не можем cd ~ «$ USER» или cd ~ $ {USER}

8

Мне любопытно, почему мы не можем переключиться на домашнего директора пользователя с

$ cd ~"$USER"

или

$ cd ~${USER}
Neo_Returns
источник
4
Потому что гораздо проще просто набрать "cd"?
jamesqf
7
@jamesqf, мы все знаем, что можно сделать .. вопрос здесь в том, что нельзя сделать и почему?
Neo_Returns

Ответы:

20

Это очень сильно зависит от оболочки и порядка выполнения расширений в этих оболочках.

~$userразворачивается в домашний каталог пользователя, имя которого хранится в $usercsh (откуда взялась эта ~userфункция), AT & T ksh, zsh, fish.

Обратите внимание на эти варианты:

$ u=daemon/xxx csh -c 'echo ~$u'
/usr/sbin/xxx  # same in zsh/fish
$ u=daemon/xxx ksh93 -c 'echo ~$u'
~daemon/xxx

$ u=daemon/xxx csh -c 'echo ~"$u"'
Unknown user: daemon/xxx.
$ u=daemon/xxx zsh -c 'echo ~"$u"'
/usr/sbin/x  # same in fish

$ u=" daemon" csh -c 'echo ~$u'
/home/stephane daemon
$ u=" daemon" zsh -c 'echo ~$u'
~ daemon  # same in ksh/fish

$ u="/daemon"  csh -c 'echo ~$u'
/home/stephane/daemon  # same in zsh
$ u="/daemon"  fish -c 'echo ~$u'
~/daemon  # same in ksh

Он расширяется до домашнего каталога пользователя, названного буквально $userв bash(при условии, что пользователь существует, что, конечно, очень маловероятно).

И ни в pdksh, dash, yash, по- видимому , потому что они не считают $user, что действительное имя пользователя.

Стефан Шазелас
источник
Подскажите, пожалуйста, где я могу узнать больше о расширении в различных оболочках?
Neo_Returns
6
@Neo_Returns, их соответствующие руководства и, когда это неясно документировано, с пробами и ошибками, а также исходный код для тех, где он доступен ...
Стефан Шазелас
10

Расширение тильды - это отдельный шаг в обработке командной строки. Это происходит как раз перед расширением переменной.

Если за тильдой следует что-то отличное от косой черты, она развернется в домашний каталог пользователя, чье имя следует за тильдой, как, например, в ~otheruser. Поскольку $USERв этот момент он не раскрывается и вряд ли соответствует действительному имени пользователя, тильда остается нерасширенной.

$USERскорее всего, это имя пользователя текущего пользователя, поэтому ваше выражение может быть заменено просто ~.

Кусалананда
источник
6

Как уже указывалось в других ответах, поведение зависит от того, в каком порядке выполняется оболочка ~и $расширения, и будет ли она вообще выполнять одно и то же слово.

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

eval "cd ~$USER"

изменится на домашний каталог пользователя, заданный именем пользователя в переменной USER, при условии, что $USERон не содержит символов, специальных для оболочки (если есть вероятность, что это возможно, вы не должны передавать его в качестве аргумента, evalпоскольку это было бы опасно ) или /символы и что есть запись для этого пользователя в базе данных пользователей системы.

kasperd
источник
3

Альтернативный способ поиска домашнего каталога переменной пользователя, если вы используете одну из оболочек, в которых расширение тильды происходит до расширения переменной, - с помощью getent . Этот инструмент существует как минимум в Linux, Solaris и FreeBSD; Я не уверен, насколько это универсально.

$ USER=bloggs
$ getent passwd "$USER" | cut -d: -f6
/home/b/bloggs

Как и в случае расширения тильды, это может не дать вам то же самое, что su - $USER -c 'echo $HOME'выглядело бы, если бы у вас были права для этого.

zwol
источник
1
Смотрите также perl -le 'print((getpwnam shift)[7])' -- "$USER"как потенциально чуть более переносимый.
Стефан Шазелас
-2

Поскольку ОП настаивает на ответе, вот оно.

Поведение этих команд (и многих других) зависит от конкретной оболочки, которую вы используете. Если вы не укажете, какую именно оболочку вы используете, возможно, будет невозможно дать простой ответ.

На самом деле, если вы используете tcsh, как и я, оба выражения в вопросе OP (как написано, когда я пишу это - я не несу ответственности за будущие правки!) Работают отлично. Я не знаю, что будут делать другие оболочки, так как я ими не пользуюсь. Так что, возможно, ОП не знает так много о том, что можно сделать, как он / она думает :-)

jamesqf
источник