Скомпилированы ли оболочки Bash, Bourne и Korn в один двоичный файл в OSX?

В OSX 10.8, если вы сравните двоичные файлы для bash, sh и ksh, несколько разных вариантов оболочки, они будут одинакового размера. Если вы пойдете дальше и cmpдвоичные файлы, разница между двоичными файлами будет только в один байт.

На первый взгляд это указывает на то, что весь код для поддержки всех различных оболочек доступен в каждом двоичном файле, но какое подмножество у вас есть доступ, зависит от того, какую оболочку вы в конечном итоге выполняете.

  1. Может ли кто-нибудь подтвердить, что двоичные файлы действительно скомпилированы таким образом?
  2. С точки зрения Apple, есть ли у них какая-либо польза от объединения всех оболочек таким образом?

Ответы (2)

Я думаю, что ваше основное предположение неверно. Проверка на 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

shС технической точки зрения между и есть некоторое сходство bash(и последний также может вести себя как sh), но kshон определенно исходит из другой исходной базы:

О да, вы определенно правы; должен был смотреть на cmp -l, а не только на cmp. Спасибо.
Интересно, что /bin/sh на самом деле является bash (хотя, судя по названию, он будет работать в режиме эмуляции sh). В некоторых прошлых версиях OS X это была либо жесткая ссылка на /bin/bash, либо идентичная копия, но, по крайней мере, в 10.8.3 она немного отличается. /bin/ksh, с другой стороны, это действительно другая программа, которая имеет примерно такой же размер.

ksh и bash совершенно разные, но двоичные файлы bash и sh в основном идентичны. OS X sh — это версия bash, которая:

  • Включен ли режим POSIX . bash по умолчанию не соответствует POSIX.
  • Имеет разное поведение при запуске. Например sh -lне читает ~/.bash_profile/.
  • xpg_echo включен по умолчанию. Так echoдействует вроде echo -eи не поддерживает никаких вариантов.

FCEDIT по умолчанию имеет значение ed в sh, но EDITOR или ed в 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}}"

Исходный код можно загрузить с http://opensource.apple.com/tarballs/ .

От человека Баш :

Если bash вызывается с именем sh, он пытается максимально точно имитировать поведение при запуске предыдущих версий sh, при этом также соответствуя стандарту POSIX.

Однако он не эмулирует другие аспекты оригинальных оболочек Bourne.

Оригинальные оболочки Bourne больше не поддерживаются, а /bin/sh теперь означает какую-то другую оболочку, которая просто соответствует POSIX. OS X sh позволяет использовать башизмы , которые не обязательно работают с /bin/sh на других платформах (например, тире в Ubuntu).