¿Por qué no funciona este softlink como se esperaba?

11
bash4.3 # pwd
/bin
bash4.3 # ll sh
lrwxrwxrwx. 1   root    root    4   May 17 22:22 sh -> bash
bash4.3 # ll bash
-rwxr-xr-x. 1   root    root    1072056 May 17 22:22 bash
bash4.3 # bash
bash4.3 # sh
sh-4.3#

Mi sistema operativo es fedora 24 (versión predeterminada de GNOME).

Por el ejemplo, podemos saber: debajo /bin, bashes un ejecutable binario; shes un enlace suave a bash.

Entonces, que yo sepa, type bash and press enterdebería producir el mismo resultado exactamente como type sh and press enter.

Cuando yo type bash and press enter, me sale [root@localhost bin]#como se esperaba.

Sin embargo, si yo type sh and press enter, sorprendentemente lo entiendo sh-4.3#.

Cual es la causa

xmllmx
fuente
El texto que podría copiarse fácilmente en un editor SE como imagen es bastante molesto, así que no lo hagas. En su lugar, seleccione el texto en su terminal y presione CTRL-SHIFT-C.
gato

Respuestas:

25

Esa es una característica documentada.

Si ejecuta bash a través de un enlace simbólico llamado sh, bash comenzará en shmodo de compatibilidad.

De man bash:

Si se invoca bash con el nombre sh, intenta imitar el comportamiento de inicio de las versiones históricas de sh lo más fielmente posible, a la vez que se ajusta al estándar POSIX. Cuando se invoca como un shell de inicio de sesión interactivo, o un shell no interactivo con la opción --login, primero intenta leer y ejecutar comandos desde / etc / profile y ~ / .profile, en ese orden. La opción --noprofile puede usarse para inhibir este comportamiento. Cuando se invoca como un shell interactivo con el nombre sh, bash busca la variable ENV, expande su valor si está definido y usa el valor expandido como el nombre de un archivo para leer y ejecutar. Como un shell invocado como sh no intenta leer y ejecutar comandos desde ningún otro archivo de inicio, la opción --rcfile no tiene ningún efecto. Un shell no interactivo invocado con el nombre sh no intenta leer ningún otro archivo de inicio. Cuando se invoca como sh, bash entra en modo posix después de leer los archivos de inicio.

¿Cómo sabe un programa qué nombre se usó para iniciarlo?

Si es un programa de CA, puede inspeccionar argv[0]. Si es un script de shell o perl, puede inspeccionar $0.

Como ejemplo, consideremos este simple script de shell:

$ cat utc
#!/bin/sh
case "${0##*/}" in
        utc) date -u ;;
        et) TZ=US/Eastern date ;;
esac

$0es el nombre con el que se llamó al script. ${0##*/}es el nombre al que se llamó el script con cualquier nombre de directorio eliminado.

Creemos este enlace simbólico:

ln -s utc et

Entonces, utcy etambos ejecutan el mismo ejecutable pero proporcionan resultados diferentes. Cuando se ejecuta como utc, genera tiempo universal. Cuando se ejecuta como et, se emite la hora del este de EE. UU. Por ejemplo:

$ utc
Wed Jul 20 18:14:18 UTC 2016
$ et
Wed Jul 20 14:14:20 EDT 2016
John1024
fuente
44
Es posible que desee agregar cómo es esto posible, ya que el OP espera que las llamadas sean idénticas. ( argv[0], obvs)
ligereza
@LightnessRacesinOrbit Buena idea. Agregué un ejemplo.
John1024
Perfecto ahora :)
ligereza corre en órbita el