~ es $ HOME, pero a veces?

14

cd ~

hace lo mismo que

cd $HOME

que también es lo mismo que

cd /home/tandu

Sin embargo,

cd ~not-tandu

cambios a /home/not-tandu

¿Es esta una elección puramente sintáctica? ¿Cómo lo maneja el kernel (o el cdejecutable)? ¿Hay un caso especial para ~agregar la barra oblicua si se omite todo lo demás? Es decir, ~/y ~cambiar al mismo directorio, pero ~aestá un directorio arriba. No se puede decir lo mismo de ningún otro directorio al que cambie.

Píldoras de explosión
fuente
3
Siéntase libre de comparar ~ not-tandu y ~ / not-tandu, uno apunta al directorio principal de usuario no-tandu y los otros puntos al directorio not-tandu en su homedir.
Johan
44
No es el kernel o el "cd ejecutable" (ya que no existe tal cosa), es un shell incorporado.
Paul Tomblin
Como no lo mencionas: cdsin ningún parámetro funciona como cd ~. Si reemplaza cdcon echopuede ver a qué expresión se expande el shell.
jofel

Respuestas:

18

~es un alias $HOMEproporcionado por una serie de shells, pero $HOMEes más universal. $HOMEen realidad le pide al shell que inserte (sustituya) la variable ambiental HOME aquí. Hay muchas variables ambientales diferentes que se pueden sustituir, intente ejecutar envuna lista. Tenga en cuenta que ~no siempre se reconoce cuando no está al comienzo de una palabra. Pruebe estos dos comandos para comparar:

ls /~
ls /$HOME

El primero se pasa al ejecutable ls, /~que luego intenta mirar un archivo llamado ~en el directorio raíz, el segundo se expande $HOMEy se convierte en el //home/userque luego se pasa al ejecutable ls como un argumento de línea de comandos. Todos los sistemas POSIX (POSIX es el estándar sobre cómo funcionan los sistemas UNIX y Linux) permiten que las barras múltiples se traten de la misma manera que una barra diagonal, //home/useres lo mismo que decir /home/user. ~usernamees un acceso directo para decirle al shell que busque el nombre de usuario en el archivo passwd y que devuelva su directorio de inicio. No hay una variable de entorno equivalente. Todas estas sustituciones son realizadas por el shell y son compatibles con la mayoría de ellas, pero solo $HOMEtodas las shells garantizan que solo las variables de entorno sean compatibles. También,cdes en realidad un comando incorporado. Es una directiva especial que le dice al propio shell que cambie los directorios. No es como otras funciones integradas de shell que se pueden implementar como un ejecutable separado como echoporque se usa para cambiar un atributo fundamental del proceso de shell. echoes simplemente un shell integrado por razones de rendimiento, pero en los viejos tiempos de UNIX, solo estaba disponible como su propio ejecutable /bin/echo.

pingüino359
fuente
re "que luego intenta mirar un archivo llamado ~ en el directorio raíz"; ¿Eso es para todos los sabores de Unix?
Pacerier
17

~foo significa 'el directorio de inicio del usuario foo'.

Esto no lo hace el kernel, lo interpreta el shell. Cada vez que el shell lo ve ~foocomo un argumento, lo reemplaza de manera transparente con el directorio de inicio del usuario fooy lo pasa en su lugar. Entonces, cuando corres cd ~tandu, el shell realmente se está ejecutando cd /home/tandu.

Patricio
fuente
1
¿Qué significa específicamente este reemplazo y con qué algoritmo? ¿Es cdo la cáscara? ¿Qué pasa si no estás ejecutando un shell? ¿Es un simple "si ~ es seguido por algo, se expande de manera diferente?" ¿O hay algún otro manejo especial para esta condición única?
Píldoras de explosión
8
Vea el manual de Bash en Tilde Expansion . (Muchos otros shells y programas siguen reglas similares.)
cjm
44
@tandu: el shell sí cd, no hay un ejecutable externo para hacerlo (no sería posible)
Mat
1
@tandu: si no está ejecutando un shell (por ejemplo, probando esto usando exec(2)), la expansión del shell no tiene lugar. Sin expansión de shell, ~no se reemplaza por nada, es solo otro personaje perfectamente válido. Esto me mordió en mis primeros días de SunOS porque /bin/shno lo asimilé ~.
Alexios
5

~ seguido de un nombre de usuario se expande al directorio de inicio de ese usuario.

Ignacio Vazquez-Abrams
fuente