¿Los shells Bash, Bourne y Korn están compilados en un binario en OSX?

En OSX 10.8, si compara los binarios para bash, sh y ksh, algunas opciones de shell diferentes, tienen el mismo tamaño. Si lo lleva más allá y cmplos binarios, parece que solo hay una diferencia de un byte entre los binarios.

Esto parece indicar superficialmente que todo el código para admitir todos los diferentes shells está disponible en cada binario, pero el subconjunto al que tiene acceso depende del shell que termine ejecutando.

  1. ¿Alguien puede confirmar que los binarios de hecho se compilan de esta manera?
  2. Desde el punto de vista de Apple, ¿tiene algún beneficio combinar todas las carcasas de esta manera?

Respuestas (2)

Creo que tu suposición básica es incorrecta. Comprobando en 10.8.3:

pse@Fourecks:~$ ls -l $(type -p sh bash ksh)
-r-xr-xr-x  1 root  wheel  1333920 Oct 16  2012 /bin/bash*
-r-xr-xr-x  1 root  wheel  1380304 Oct 16  2012 /bin/ksh*
-r-xr-xr-x  1 root  wheel  1334000 Oct 16  2012 /bin/sh*
pse@Fourecks:~$ cmp -l $(type -p sh bash) | wc -l
cmp: EOF on /bin/bash
 1138124
pse@Fourecks:~$ cmp -l $(type -p sh ksh) | wc -l
cmp: EOF on /bin/sh
 1238180

Técnicamente hablando, hay algunas similitudes entre shy bash(y el último también se puede hacer para que se comporte como sh), pero kshdefinitivamente proviene de una base de origen diferente:

Oh sí, definitivamente tienes razón; debería haber estado mirando cmp -l en lugar de solo cmp. Gracias.
Curiosamente, /bin/sh en realidad es bash (aunque se ejecutará en modo de emulación sh según el nombre). En algunas versiones anteriores de OS X ha sido un enlace fijo a /bin/bash o una copia idéntica, pero al menos en 10.8.3 es ligeramente diferente. /bin/ksh, por otro lado, es un programa realmente diferente que tiene aproximadamente el mismo tamaño.

ksh y bash son completamente diferentes, pero los binarios de bash y sh son en su mayoría idénticos. sh de OS X es una versión de bash que:

  • Tiene el modo POSIX habilitado. bash no cumple con POSIX por defecto.
  • Tiene un comportamiento de inicio diferente. Por ejemplo sh -l, no lee ~/.bash_profile/.
  • Tiene xpg_echo habilitado por defecto. Entonces echoactúa como echo -ey no admite ninguna opción.

El FCEDIT predeterminado es ed en sh pero EDITOR o ed en bash:

$ diff -y --suppress-common-lines -W 80 <(strings /bin/bash) <(strings /bin/sh)
                                      > /bin/bash
${FCEDIT:-${EDITOR:-ed}}              | ${FCEDIT:-ed}
@(#)PROGRAM:bash  PROJECT:bash-86.1   | @(#)PROGRAM:sh  PROJECT:bash-86.1
$ grep -rF '${FCEDIT:-${EDITOR:-ed}}' ~/Code/Source/bash-86.1/
bash-86.1/bash-3.2/builtins/fc.c:#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
bash-86.1/bash-3.2/builtins/fc.def:#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"

La fuente se puede descargar desde http://opensource.apple.com/tarballs/ .

De man bash :

Si bash se invoca con el nombre sh, intenta imitar el comportamiento de inicio de las versiones históricas de sh lo más fielmente posible, mientras también se ajusta al estándar POSIX.

Sin embargo, no emula otros aspectos de los proyectiles Bourne originales.

Los shells originales de Bourne ya no se mantienen, y /bin/sh ahora está destinado a ser otro shell que solo cumple con POSIX. sh de OS X permite usar bashisms que no necesariamente funcionan con /bin/sh en otras plataformas (como dash en Ubuntu).