¿Cuál es la diferencia entre el hogar $ y ~ $?

Estoy aprendiendo Linux, y estoy un poco confundido en este momento. En la siguiente captura de pantalla, no pude entender el tercer atajo de la Tabla 2-1 .

Dice que cd ~user_name cambiará el directory de trabajo al directory de inicio de user_name . Pero, cuando ingresé este command, estaba en el mismo directory, es decir, ~ $ y no en / home $ . ¿Por qué?

¿Son ambos lo mismo?

Creo que el formal es el directory de usuarios y el último es el directory de inicio.

Lo siento si le pregunté algo tonto, ¡y gracias de antemano!

Captura de pantalla

Lo que sea que diga sobre ~ $ , home $ y / home $ no tiene mucho sentido. Supongo que estás hablando de tu línea de command; de ser así, hubiera sido útil mostrar lo que escribió y lo que sucedió (y luego explicó lo que esperaba).

Pero puedo leer las mentes, así que creo que entiendo el problema: ~ y ~ user239887 (suponiendo que el user239887 es su nombre de usuario real) significa lo mismo. Si fueras a escribir

 cd ~gman 

eso lo llevaría a mi directory de inicio, y su intérprete de commands probablemente se parecería a /home/gman$ .


Al principio, el indicador del shell siempre tenía dos caracteres: un carácter de printing y un espacio. Si fue un administrador del sistema, su post fue " # "; de lo contrario, era " $ " o " % ". Y luego Dios dijo, "Que haya indicaciones de concha extravagantes", y, he aquí, hubo indicaciones de shell extravagantes. Las indicaciones de Shell comenzaron a mostrar el nombre del usuario, el nombre del sistema, la hora y la fase de la luna (¿crees que estoy bromeando?), Todo en color.

Una de las personalizaciones más populares para el intérprete de commands del shell es include el directory actual. Su request de shell es probablemente su directory actual seguido de " $ ".

Otra cosa interesante ™ fue que pudiste especificar tu propio directory de inicio escribiendo " ~ ". Debido a esto, cuando su directory actual es su directory de inicio y su indicador de commands del shell está configurado para mostrar su directory actual, entonces el indicador del shell muestra " ~ ". Pero en cualquier otro lugar, muestra el nombre de ruta real (excepto que podría mostrar " ~gman " cuando estás en mi directory de inicio, /home/gman ).

Su directory de inicio es probablemente /home/user239887 . Como dije antes, puede referirse a él como ~ o ~ user239887 . Cuando inicie session, se encuentra en su directory de inicio, por lo que su post es " ~$ ". Si escribe cd .. , irá al directory /home , que es el directory principal de su directory personal, y su post se convertirá en " /home$ ".

A riesgo de repetirme, NO /home no es su directory personal. Su directory de inicio es probablemente /home/user239887 . /home es el directory principal de su directory personal.

En shell, el directory de inicio del usuario se encuentra en /home/username ,

~ es un acceso directo para el directory de inicio del usuario actual que usa el shell,

~usr es un acceso directo para el directory principal del usuario con el usuario usr , por lo tanto ~usr es lo mismo que /home/usr . Si su nombre de usuario es usr , entonces ~ y ~usr son lo mismo.

El directory de inicio del usuario actual también se guarda en la variable $HOME .

La variable de entorno $HOME normalmente se establece y exporta al login en la ruta del directory de inicio de un usuario cuando un usuario inicia session. Un shell compatible con POSIX usará el valor de esta variable de entorno en un context cuando debería realizar una expansión de tilde para completar una ruta al directory de inicio de un usuario, pero el campo expandido real es nulo de otra manera. Además de su asociación con la expansión de shell tilde y con /bin/login la variable de shell $HOME no es en ningún otro caso excepcional, es manejada por el shell como podría ser cualquier otra variable de shell. Sin embargo, la expansión de la tilde de la caparazón es única ya que las expansiones de caparazón entran en casi todos los sentidos.

Esto es un poco difícil de comprender al principio, y es probablemente la razón por la cual la expansión de la tilde es tan poco utilizada a pesar de su inmunidad a los diversos types de vulnerabilidades de expansión de shell que a menudo pueden afectar negativamente a los types más comunes.

El intérprete de commands podría considerar portablemente una tilde elegible para la expansión si se lee en cualquiera de los siguientes contexts:

  1. Sigue inmediatamente el primer = o cualquier carácter de dos puntos en una asignación de variables de shell.
  2. Comienza cualquier palabra de argumento de shell.
  3. Comienza una ruta de shell y completa al less un componente de ruta completamente delimitado por sí solo o puede hacerlo de manera verificable con el context final.

Incluso en estos casos, la tilde no se expandirá si se cita, o si el context de algún modo impide su expansión total al directory de inicio de algún usuario o al valor actual de la variable de entorno $HOME . En otras palabras, el shell no realizará expansiones de tilde si el context de la expansión es incierto. Mientras que el shell ampliará felizmente $var_not_var a null, se negará cada vez a hacer conjeturas similares sobre un ~ .

La sustitución de $HOME , por ejemplo, solo puede ocurrir si el campo de expansión posible de la tilde es nulo, lo que quiere decir que su position en la list de arguments garantiza inequívocamente su elegibilidad para la expansión porque está delimitada por todos lados.

El único otro caso en el que se puede expandir una tilde es cuando su context final coincide completamente con un nombre de usuario del sistema verificado, en cuyo caso se sustituye por una ruta al directory inicial asignado de dicho usuario según lo informa el sistema. El shell debe comparar el context con una list de usuarios registrados del sistema y solo expandirse si el context final coincide con uno de ellos.

Para aclarar lo que quiero decir con un campo de expansión nulo o no nulo , aquí hay algunos ejemplos:

 printf %s\\n ~some_user_name ~some_user_name/some_more_stuff 

Los dos contexts de expansión anteriores no son nulos: la tilde solo se puede expandir al nombre de la ruta del directory principal de algunos usuarios y solo si existe un nombre de usuario registrado en el sistema actual. El segundo ~ debe expandirse (o no expandirse) de manera idéntica al primero porque el carácter de ruta / separador delimita el context final. Si el intérprete de commands no puede verificar la existencia de algún_nombre_de_usuario , el ~ debe seguir siendo solo una tilde .

 printf %s\\n ~/some_user_name /~/ ~ 

Pero aquí los campos de expansión para la primera y la tercera tildes son nulos. El primero está delimitado por el separador de ruta char. El segundo está delimitado de manera similar, pero ni siquiera se considera para expansión porque no lleva la palabra de shell. La primera y la tercera tildes deberían expandirse al valor actual de la variable de entorno $HOME , y los resultados de la expansión deberían ser equivalentes a:

 printf %s\\n "$HOME"/some_user_name /~/ "$HOME" 

Tenga en count que la ruta "$HOME"/some_user_name anterior no necesita existir para calificar la tilde para la expansión, como también es cierto para el anterior ~some_user_name/some_more_stuff example, que es un atributo único entre las expansiones de routes portátiles. ¿ Generación de nombre de file típica o comportamiento de globbing de shell como podría intentarse con los caracteres especiales de shell ?[* Solo es para expandir estos caracteres si coinciden con un nombre de ruta resuelto pero si no para que permanezcan literalmente. Sin embargo, la tilde adopta un valor arbitrario preasignado , como se especifica en $HOME , cuando no se puede tener una coincidencia, siempre que su elegibilidad de expansión sea absoluta.

Tenga en count también que las citas utilizadas anteriormente son intencionales, mientras que la expansión de la tilde no se producirá entre comillas, el valor de su expansión siempre es literal y nunca está sujeto a nuevas expansiones de nombres de routes o divisiones de shell de ningún tipo. Se expande de la misma manera que la mayoría de las otras expansiones requieren citas para hacer, cuando se expande en absoluto. Esto es (posiblemente muy útil) contrastado, por supuesto, por el comportamiento de expansión de la variable de entorno $HOME real.

Como indiqué anteriormente, la expansión de tilde solo puede ocurrir en un context de argumento o asignación a less que la expansión complete un componente de path delimitado de un command ejecutable. Y por lo tanto, un ~ pasado solo en position de command no estará sujeto a expansión. Por lo tanto, es posible asignar un ~ alias shell tal que el command:

 ~ ~ 

… da como resultado dos valores ampliados de forma independiente y única que se procesan completamente en function del context de input. Un usuario incluso podría definir el ~ alias para definir el valor de la variable de shell $HOME cuando se llame de modo que la expansión de la segunda tilde sea ​​alterada por la primera (y posiblemente incluso viceversa con la recursión) .

De hecho, me gusta pensar en la tilde como una especie de argumento alias . A menudo lo uso en combinación con $IFS , cuyos efectos son inmunes, y $* y eval . Considero que se presta muy bien a $IFS contexts $IFS porque, como un solo carácter, puede eliminarse de una cadena por completo con una sola expansión, o bien sustituir de forma segura en cualquier número de caracteres por ocurrencia como yo lo desee. Una matriz de arguments que se ve así:

 "$argv1" ~ "$argv2" ~ "$argv3" ~ 

… podría ser (con security) cualquier cantidad de cosas en un momento dado al reasignar el valor de $HOME a lo que desee y volver a eval temporalmente. Tal matriz de arguments puede incluso generarse a partir de cualquier otro en los puntos del delimitador del argumento original con una aplicación algo diestra de $* sustituciones.

Otra construcción que me gusta usar es:

 for HOME in ./* ~; do stuff w/ $HOME and ~; done 

… que me da dos valores para la asignación de cada iteración. A uno de ellos puedo aplicar libremente el análisis en forma de split de $IFS o caracteres globales adicionales inmediatamente junto con el otro, que siempre se referirá literalmente al valor del argumento original de la iteración. Y, lo que es más, puedo hacer estas cosas lado a lado en la misma list de arguments del command y sin abarrotarlo demasiado con comillas de shell.

Es este último punto, creo, el que demuestra más claramente la diferencia entre $HOME y ~ .