cd ~ <user> est possible mais pourquoi ne pouvons-nous pas cd ~ "$ USER" ou cd ~ $ {USER}

8

Je suis curieux de savoir pourquoi nous ne pouvons pas passer au directeur de la maison d'un utilisateur avec

$ cd ~"$USER"

ou

$ cd ~${USER}
Neo_Returns
la source
4
Parce que c'est tellement plus simple de taper "cd"?
jamesqf
7
@jamesqf, nous savons tous ce qui peut être fait .. la question ici est de savoir ce qui ne peut pas être fait et pourquoi?
Neo_Returns

Réponses:

20

Cela dépend beaucoup du shell et de l'ordre dans lequel les extensions sont effectuées dans ces shells.

~$userse développe dans le répertoire personnel de l'utilisateur dont le nom est stocké dans $usercsh (d'où ~uservient cette fonctionnalité), AT&T ksh, zsh, fish.

Notez cependant ces variations:

$ 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

Il se développe dans le répertoire personnel de l'utilisateur nommé littéralement $userdans bash(à condition que cet utilisateur existe, ce qui est très peu probable bien sûr).

Et ni dans pdksh, dash, yash, probablement parce qu'ils ne considèrent pas $usercomme un nom d'utilisateur valide.

Stéphane Chazelas
la source
Pouvez-vous me suggérer où puis-je en savoir plus sur l'expansion dans divers obus.
Neo_Returns
6
@Neo_Returns, leurs manuels respectifs, et quand ce n'est pas clairement documenté, avec essais et erreurs et le code source pour ceux où il est disponible ...
Stéphane Chazelas
10

L'expansion de Tilde est une étape distincte du traitement de la ligne de commande. Cela se produit juste avant l' expansion variable.

Si le tilde est suivi par autre chose qu'une barre oblique, il se développera dans le répertoire personnel de l'utilisateur dont le nom suit le tilde, comme dans, par exemple ~otheruser,. Étant donné qu'il $USERn'est pas développé à ce stade et qu'il est peu probable qu'il corresponde à un nom d'utilisateur valide, le tilde n'est pas développé.

$USERest probablement le nom d'utilisateur de l'utilisateur actuel, donc votre expression pourrait probablement être remplacée par juste ~.

Kusalananda
la source
6

Comme d'autres réponses l'ont souligné, le comportement dépend de l'ordre du shell ~et des $extensions et s'il fera les deux pour le même mot.

Le comportement que vous recherchiez peut être obtenu en bashmodifiant très légèrement votre commande. Préfixez simplement la commande avec eval.

eval "cd ~$USER"

changera dans le répertoire personnel de l'utilisateur donné par le nom d'utilisateur dans la variable USER, à condition $USERqu'il ne contienne pas de caractères spéciaux pour le shell (s'il y a une chance éloignée qu'il le soit, vous ne devriez pas le passer comme argument evalcar cela serait dangereux ) ou des /caractères et qu'il existe une entrée pour cet utilisateur dans la base de données utilisateur du système.

kasperd
la source
3

Une autre façon de rechercher le répertoire personnel d'un utilisateur variable, si vous utilisez l'un des shells où l'expansion tilde se produit avant l'expansion variable, est avec getent . Cet outil existe au moins sur Linux, Solaris et FreeBSD; Je ne sais pas à quel point c'est universel.

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

Comme pour l'expansion de tilde, cela pourrait ne pas vous donner la même chose qui su - $USER -c 'echo $HOME's'imprimerait si vous aviez les privilèges de le faire.

zwol
la source
1
Voir aussi perl -le 'print((getpwnam shift)[7])' -- "$USER"comme potentiellement légèrement plus portable.
Stéphane Chazelas
-2

Puisque le PO insiste sur une réponse, la voici.

Le comportement de ces commandes (et bien d'autres choses) dépend du shell particulier que vous utilisez. À moins que vous ne spécifiiez quel shell particulier vous utilisez, il n'est probablement pas possible de donner une réponse simple.

En fait, si vous utilisez tcsh, comme je le fais, les deux expressions de la question de l'OP (telles qu'elles sont écrites au moment où j'écris ceci - je ne prends aucune responsabilité pour les futures modifications!) Fonctionnent parfaitement. Je ne sais pas ce que feront les autres obus, car je ne les utilise pas. Alors peut-être que l'OP n'en sait pas autant sur ce qui peut être fait qu'il le pense :-)

jamesqf
la source