Как и кто определяет, что выполняется, когда Bash-подобный скрипт выполняется как двоичный файл без шебанга?
Я полагаю, что при запуске нормального скрипта с шебанг обрабатывается с помощью binfmt_script Модуль Linux, который проверяет shebang, анализирует командную строку и запускает назначенный интерпретатор сценариев.
Но что происходит, когда кто-то запускает сценарий без shebang?Я проверил прямой execv
подход и обнаружил, что в нем нет магии ядра - то есть такой файл:
$ cat target-script
echo Hello
echo "bash: $BASH_VERSION"
echo "zsh: $ZSH_VERSION"
Запуск скомпилированной программы на C, которая выполняет только вызов execv
, дает:
$ cat test-runner.c
void main() {
if (execv("./target-script", 0) == -1)
perror();
}
$ ./test-runner
./target-script: Exec format error
Однако, если я делаю то же самое из другого сценария оболочки, он запускает целевой сценарий, используя тот же интерпретатор оболочки, что и исходный:
$ cat test-runner.bash
#!/bin/bash
./target-script
$ ./test-runner.bash
Hello
bash: 4.1.0(1)-release
zsh:
Если я выполняюТот же трюк с другими оболочками (например, по умолчанию в Debian sh
- /bin/dash
), он также работает:
$ cat test-runner.dash
#!/bin/dash
./target-script
$ ./test-runner.dash
Hello
bash:
zsh:
Таинственным образом, он не совсем работает, как ожидается, с zsh и не следуетобщая схема.Похоже, zsh в конце концов выполнил /bin/sh
для таких файлов:
greycat@burrow-debian ~/z/test-runner $ cat test-runner.zsh
#!/bin/zsh
echo ZSH_VERSION=$ZSH_VERSION
./target-script
greycat@burrow-debian ~/z/test-runner $ ./test-runner.zsh
ZSH_VERSION=4.3.10
Hello
bash:
zsh:
Обратите внимание, что ZSH_VERSION
в родительском скрипте работал, в то время как ZSH_VERSION
в дочернем не работал!
Как это работаетоболочка (Bash, Dash) определяет, что будет выполнено, когда нет шебанга?Я пытался откопать это место в источниках Bash / Dash, но, увы, похоже, я там немного заблудился.Может ли кто-нибудь пролить свет на магию, которая определяет, должен ли целевой файл без shebang быть выполнен как скрипт или как двоичный файл в Bash / dash?Или, может быть, это какое-то взаимодействие с ядром / libc, и тогда я хотел бы получить объяснения о том, как это работает в ядрах / libcs Linux и FreeBSD?