cd ~ <user> es posible, pero ¿por qué no podemos cd ~ "$ USER" o cd ~ $ {USER}

8

Tengo curiosidad por qué no podemos cambiar al director de casa de un usuario con

$ cd ~"$USER"

o

$ cd ~${USER}
Neo_Returns
fuente
44
¿Porque es mucho más simple escribir "cd"?
jamesqf
77
@jamesqf, todos sabemos lo que se puede hacer ... la pregunta aquí es qué no se puede hacer y por qué.
Neo_Returns

Respuestas:

20

Eso depende mucho del caparazón y del orden en que se realizan las expansiones en esos caparazones.

~$userse expande al directorio de inicio del usuario cuyo nombre se almacena en $usercsh (de donde ~userproviene esa característica), AT&T ksh, zsh, fish.

Sin embargo, tenga en cuenta estas variaciones:

$ 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

Se expande al directorio de inicio del usuario nombrado literalmente $useren bash(siempre que exista el usuario, lo cual es muy poco probable, por supuesto).

Y ni en pdksh, dash, yash, presumiblemente debido a que no consideran $userque ser un nombre de usuario válido.

Stéphane Chazelas
fuente
¿Puede sugerirme dónde puedo obtener más información sobre la expansión en varios shells?
Neo_Returns
66
@Neo_Returns, sus respectivos manuales, y cuando eso no está claramente documentado, con prueba y error y el código fuente para aquellos donde está disponible ...
Stéphane Chazelas
10

La expansión de Tilde es un paso separado en el procesamiento de la línea de comando. Sucede justo antes de la expansión variable.

Si la tilde es seguida por algo que no sea una barra inclinada, se expandirá al directorio de inicio del usuario cuyo nombre sigue a la tilde, como en, por ejemplo ~otheruser,. Como $USERno se expande en ese punto y es poco probable que corresponda a un nombre de usuario válido, la tilde se deja sin expandir.

$USERes probable que sea el nombre de usuario del usuario actual, por lo que su expresión probablemente podría reemplazarse por solo ~.

Kusalananda
fuente
6

Como otras respuestas han señalado, el comportamiento depende del orden que haga el shell ~y las $expansiones, y de si incluso hará ambas cosas por la misma palabra.

Es posible lograr el comportamiento que estaba buscando bashmediante un cambio muy pequeño en su comando. Simplemente prefija el comando con eval.

eval "cd ~$USER"

cambiará al directorio de inicio del usuario dado por el nombre de usuario en la variable USER, siempre $USERque no contenga caracteres especiales para el shell (si existe una remota posibilidad de que pueda, no debe pasarlo como argumento evalya que sería peligroso ) o /caracteres y que hay una entrada para ese usuario en la base de datos de usuarios del sistema.

kasperd
fuente
3

Una forma alternativa de buscar el directorio de inicio de un usuario variable, si está utilizando uno de los shells donde se produce la expansión de tilde antes de la expansión variable, es con getent . Esta herramienta existe en al menos Linux, Solaris y FreeBSD; No estoy seguro de cuán universal es.

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

Al igual que con la expansión de tilde, esto podría no darle lo mismo que su - $USER -c 'echo $HOME'imprimiría si tuviera los privilegios para hacerlo.

zwol
fuente
1
Vea también perl -le 'print((getpwnam shift)[7])' -- "$USER"como potencialmente un poco más portátil.
Stéphane Chazelas
-2

Dado que el OP insiste en una respuesta, aquí está.

El comportamiento de esos comandos (y muchas otras cosas) depende del shell particular que esté utilizando. A menos que especifique qué shell en particular usa, probablemente no sea posible dar una respuesta simple.

De hecho, si usa tcsh, como lo hago yo, ambas expresiones en la pregunta del OP (como está escrito mientras escribo esto, ¡no me responsabilizo por futuras ediciones!) Funcionan perfectamente. No sé qué harán otros proyectiles, ya que no los uso. Entonces, quizás el OP no sabe tanto sobre lo que se puede hacer como piensa :-)

jamesqf
fuente