Модули, перечисленные в /etc/mkinitcpio.conf
включены в intitrd, когда он сгенерирован с mkinitcpio -p linux
. Это загружает временную файловую систему в память и должно включать модули, необходимые для создания этого успешно, в зависимости от установки.
Пример добавил бы raid1
к Вашей строке модулей в /etc/mkinitcpio.conf
собрать массив Raid1.
В Вашей строке модулей в /etc/rc.conf
необходимо было бы только включать модули, которые автоматически не загружаются udev
но это, которого можно потребовать для запуска определенных приложений однажды файловые системы, смонтировано, такой как fuse
или loop
.
Примечание: в случае Массива RAID Вы также включали бы USEDMRAID="yes"
в Вашем /etc/rc.conf
Хижина #!
человекочитаемый экземпляр магического числа, состоящего из строки байтов 0x23 0x21
, который используется exec()
семейство функций, чтобы определить, является ли файл, который будет выполняться, сценарием или двоичным файлом. Когда хижина присутствует, exec()
выполнит исполняемый файл, указанный после хижины вместо этого.
Обратите внимание, что это означает что при вызове сценария путем определения интерпретатора на командной строке как сделан в обоих случаях данный в вопросе, exec()
выполнит интерпретатор, указанный на командной строке, он даже не посмотрит на сценарий.
Так, как другие отметили, если Вы хотите exec()
для вызова интерпретатора, указанного на строку хижины, сценарий должен иметь исполняемый набор битов и вызванный как ./my_shell_script.sh
.
Поведение легко продемонстрировать со следующим сценарием:
#!/bin/ksh
readlink /proc/$$/exe
Объяснение:
#!/bin/ksh
определяет ksh
быть интерпретатором.
$$
содержит PID текущего процесса.
/proc/pid/exe
символьная ссылка на исполняемый файл процесса (по крайней мере, на Linux; на AIX/proc/$$/object/a.out является ссылкой на исполняемый файл).
readlink
произведет значение символьной ссылки.
Пример:
Примечание: Я демонстрирую это на Ubuntu, где оболочка по умолчанию /bin/sh
символьная ссылка состоит в том, чтобы подчеркнуть штриховой линией т.е. /bin/dash
и /bin/ksh
символьная ссылка на /etc/alternatives/ksh
, который в свою очередь является символьной ссылкой на /bin/pdksh
.
$ chmod +x getshell.sh
$ ./getshell.sh
/bin/pdksh
$ bash getshell.sh
/bin/bash
$ sh getshell.sh
/bin/dash
Да это делает. По тому, как это не глупый вопрос. Ссылка для моего ответа здесь. Запуск Сценария С #!
Это называют хижиной или строкой "удара".
Это - только полный путь к интерпретатору Bash.
Это состоит из знака номера и символа восклицательного знака (#!), сопровождаемый полным путем к интерпретатору, такому как/bin/bash.
Все сценарии в соответствии с Linux выполняют использование интерпретатора, указанного на первой строке, Почти все сценарии удара часто начинаются с #!/bin/bash (предполагающий, что Bash был установлен в / мусорном ведре), Это гарантирует, что Bash будет использоваться для интерпретации сценария, даже если это будет выполняться под другой оболочкой. Хижина была представлена Dennis Ritchie между Unix Версии 7 и 8 в Bell Laboratories. Это было затем также добавлено к строке BSD в Беркли.
Игнорирование строки интерпретатора (хижина)
Если Вы не указываете строку интерпретатора, значение по умолчанию обычно является/bin/sh. Но, рекомендуется установить #!/bin/bash строка.
#!/usr/bin/perl
#!/usr/local/bin/python
#!/usr/local/bin/ruby
Другая общая запись хижины, используемая для поддержки нескольких систем, должна использовать ENV для определения местоположения интерпретатора, как который Вы хотите использовать, #!/usr/bin/env perl
#!/usr/bin/env python
– sambler
21.08.2013, 10:31
env
, который должен быть на самом деле предпочтен? Python и Perl часто используют env
, в то время как на сценариях оболочки, это часто опускается, и хижина указывает на рассматриваемую оболочку.
– polemon
21.08.2013, 13:22
Из того, что я собрался, каждый раз, когда файл имеет исполняемый набор битов и вызывается, ядро анализирует заголовок файла, чтобы определить, как продолжить двигаться (насколько я знаю, можно добавить пользовательские обработчики для пользовательских форматов файлов через LKMs). Если файл, кажется, текстовый файл с #! комбинация в начале, его выполнение отправлено другому исполняемому файлу (обычно своего рода оболочка), путь, к которому должен быть указан непосредственно после упомянутой хижины, в той же строке. Ядро затем продолжает выполнять оболочку и передавать файл для него для обработки.
Короче говоря, это не имеет значения, какая оболочка Вы вызываете сценарий с - ядро отправит выполнение соответствующему так или иначе.
Фактически, если вы так понимаете, исполняемый файл, указанный в строке shebang, является просто исполняемым файлом. Имеет смысл использовать какой-нибудь текстовый интерпретатор в качестве исполняемого файла, но в этом нет необходимости. Просто для пояснения и демонстрации я провел довольно бесполезный тест:
#!/bin/cat
useless text
more useless text
still more useless text
Назвал файл test.txt и установил исполняемый бит chmod u + x test.txt
, затем «назвал» его: ./test.txt
. Как и ожидалось, выводится содержимое файла. В этом случае кошка не игнорирует линию шебанг. Он просто выводит все строки. Таким образом, любой полезный интерпретатор должен иметь возможность игнорировать эту строку shebang. Для bash, perl и PHP это просто строка комментария. Так что да, они игнорируют строку shebang.
Системный вызов exec
ядра Linux изначально понимает шебанги(#!
)
Я не заметил, что OP спрашивал об AIX, я собираюсь сказать, что я знаю о Linux, и держу пари, что есть сильные аналогии или, по крайней мере, удовлетворят большинство гуглеров, которые ищут Linux:-)
Когда вы делаете на bash:
./something
в Linux вызывает системный вызов exec
с путем ./something
.
Эта строка ядра вызывается для файла, переданного вexec
:https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
Он читает самые первые байты файла и сравнивает их с #!
.
Если сравнение верно, то оставшаяся часть строки анализируется ядром Linux, которое выполняет еще один exec
вызов с путем /usr/bin/env python
и текущим файлом в качестве первого аргумента:
/usr/bin/env python /path/to/script.py
, и это работает для любого языка сценариев, который использует #
в качестве символа комментария.
И да, вы можете сделать бесконечный цикл с помощью:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
Bash распознает ошибку:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#!
просто удобочитаемо для человека, но это не обязательно.
Если бы файл начинался с других байтов, то системный вызов exec
использовал бы другой обработчик. Другой наиболее важный встроенный -обработчик предназначен для исполняемых файлов ELF :https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, который проверяет байты 7f 45 4c 46
(, которые также могут быть читаемы человеком для.ELF
). Давайте подтвердим это, прочитав 4 первых байта /bin/ls
, который является исполняемым файлом ELF:
head -c 4 "$(which ls)" | hd
выход:
00000000 7f 45 4c 46 |.ELF|
00000004
Таким образом, когда ядро видит эти байты, оно берет файл ELF, корректно помещает его в память и запускает с ним новый процесс. См. также:https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Наконец, вы можете добавить свои собственные обработчики shebang с помощью механизма binfmt_misc
. Например, вы можете добавить пользовательский обработчик для .jar
файлов .Этот механизм даже поддерживает обработчики по расширению файла. Другое применение — прозрачный запуск исполняемых файлов другой архитектуры с помощью QEMU .
Однако я не думаю, что POSIX определяет шебанги :https://unix.stackexchange.com/a/346214/32558, хотя упоминает об этом в разделах обоснования и в форме "если исполняемые скрипты поддерживаются системой, что-то может произойти".
exec()
упомянутый в этом ответе системный вызов, командаexec
встроенная оболочка, который является, почему Вы не можете вызватьexec
программа от Node.js или Java. Однако любая команда оболочки, вызванная, например.Runtime.exec()
в Java в конечном счете обрабатываетсяexec()
системный вызов. – Thomas Nyman 11.12.2016, 18:02child_process.{exec(),execFile(),spawn()
} все были бы реализованы с помощью Cexec()
(черезprocess
). – Thomas Nyman 12.12.2016, 05:02