Как и кто определяет, что выполняется, когда Bash-подобный скрипт выполняется как двоичный файл без шебанга?
Я предполагаю, что запуск обычного скрипта с shebang обрабатывается с помощью binfmt_script Linux-модуль, который проверяет шебанг, анализирует командную строку и запускает назначенный интерпретатор сценариев.
Но что происходит, когда кто-то запускает скрипт без шебанга? Я протестировал прямой подход 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?
target-script
с разными оболочками напрямую (например,bash target-script
илиdash target-script
), а не создавать средство запуска тестов для каждой оболочки. Это должно дать такие же результаты. - person Piotr Dobrogost   schedule 09.10.2014target-script
нет строки shebang, так какую магию ядра вы ожидаете здесь? Если вы хотите протестировать магию ядра, вы должны были поместить строку shebang в свой скрипт (только для этого теста). - person Piotr Dobrogost   schedule 09.10.2014