LINUX.ORG.RU

ld.so и bash

 , ,


0

2

Немного покрашился мирок...

Распаковал initrd и увидел, что init, который находится в корне на самом деле является скриптом bash. Отсюда вопрос:

Получается, что ядро парсит указатель на интерпретатор файла в начале? А если строчка типа «#!/bin/bash» отсутствует, то ядро всеровно запускает bash?

Тоесть получается, после вызова exec для скрипта, ядро ищет в файле указатель на интерпретатор, а затем, если интерпретатор является бинарным исполняемым файлом - запускает указанный в нем прелоадер (ld)?

Очень хотелось бы услышать просто на пальцах. Заранее спасибо.

Вообще, init может быть как интерпретируемым скриптом, так и скомпилированным бинарником.

Шебанг парсится интерпретатором (в случае с initramfs это /bin/sh). Если его нет, то sh будет выполнять код от себя (считай, что если шебанга нет, то он у тебя #!/bin/sh), если он присутствует, то он сам отбрасывается, и этой строке передаётся тело скрипта. Там может быть любой бинарник или скрипт, может быть даже просто набор текста, не являющийся интерпретатором (а значит скрипт с инвалидным шебангом просто не будет запускаться).

Это если совсем просто. На деле может быть гораздо хитрее.

r3lgar ★★★★★
()
Ответ на: комментарий от r3lgar

Тоесть рабор строки типа '#!/bin/sh' реализован в ядре? А возможно изменить дефолтный интерпретатор (те если указатель не будет найден, чтобы по умолчанию вызывался bash)?

cyber_eagle
() автор топика
Ответ на: комментарий от cyber_eagle

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

cyber_eagle
() автор топика
Ответ на: комментарий от cyber_eagle

Дело в том, что в initrd файла /etc/passwd я не нашел... информация о дефолтном пути к интерпретатору должна хранится в другом месте...

cyber_eagle
() автор топика

что init, который находится в корне на самом деле является скриптом bash.

А почему вы уверены, что ядро вызывает /init ? Ядро, если не указана опция у boot-лоадера грузит /sbin/init (ну это у Linux, изначально в Unix вообще из /etc/init было). И таки да, шебанг парсится ядром, и именно это и называется ядерным интерпретатором.

vodz ★★★★★
()

initrd и увидел, что init, который находится в корне на самом деле является скриптом bash.

Все верно. И там не bash, а ash. После сових действий:

/usr/bin/switch_root /new_root $init "$@"
int13h ★★★★★
()
Ответ на: комментарий от int13h

Все верно.

В смысле «всё верно»? То что в корне - это не init, это скорее init.rc . С таким же успехом скрипт может быть на чём угодно. Да хоть и на bash, делов то полтора мега с библиотеками положить в initrd и сжать :)

vodz ★★★★★
()

Получается, что ядро парсит указатель на интерпретатор файла в начале?

Да, ядро проверяет, начинается ли файл на «#!».

А если строчка типа «#!/bin/bash» отсутствует, то ядро всеровно запускает bash?

$ echo 1234 > wtf
$ chmod +x wtf
$ strace -e execve perl -E'exec {"./wtf"} "./wtf" or die $!'
<...>
execve("./wtf", ["./wtf"], [/* 47 vars */]) = -1 ENOEXEC (Exec format error)
<...>

Ядро вернёт ошибку. Если такая фигня произойдёт с файлом init, будет kernel panic: no init found.

Bonus content: если вы запустите пример, то увидите, что запускается всё-таки /bin/sh. Это срабатывает стандартная библиотека языка C. Ядро попыток запустить sh делать не будет.

anonymous
()
Ответ на: комментарий от anonymous

Получается, что ядро парсит указатель на интерпретатор файла в начале?

Да, ядро проверяет, начинается ли файл на «#!».

А если строчка типа «#!/bin/bash» отсутствует, то ядро всеровно запускает bash?

$ echo 1234 > wtf $ chmod +x wtf $ strace -e execve perl -E'exec {"./wtf"} "./wtf" or die $!' <...> execve("./wtf", ["./wtf"], [/* 47 vars */]) = -1 ENOEXEC (Exec format error) <...> Ядро вернёт ошибку. Если такая фигня произойдёт с файлом init, будет kernel panic: no init found.

Bonus content: если вы запустите пример, то увидите, что запускается всё-таки /bin/sh. Это срабатывает стандартная библиотека языка C. Ядро попыток запустить sh делать не будет.

Всем спасибо! Все опять на своих местах. Все красиво.

cyber_eagle
() автор топика
Ответ на: комментарий от cyber_eagle

Тоесть рабор строки типа '#!/bin/sh' реализован в ядре?

парсится интерпретатором
sh будет выполнять код

r3lgar ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.