сценарии оболочки все еще работают без #! (строка sha-bang)

10

Я новичок в сценариях оболочки, и многие книги написали, что для запуска интерпретатора используется строка #! (Sha-bang) при запуске сценария. И это вызовет новую оболочку для сценария и выполнит интерпретацию строка за строкой. моего основного сценария все еще работает без магической линии.

так что мои вопросы:

  • откуда мой основной сценарий получил переводчика.
  • Как удалось сценарию найти переводчика.

Теперь позвольте мне рассказать вам о моем базовом скрипте, он просто содержит следующую строку:

echo "основной скрипт без магических линий"

user1678213
источник

Ответы:

3

Если волшебная строка не указана, для запуска скрипта используется оболочка по умолчанию. Эта оболочка по умолчанию может быть либо оболочкой Bourne (sh), что имеет место в некоторых вариантах, однако в некоторых других вариантах используется оболочка по умолчанию, аналогичная оболочке входа в систему для ее выполнения. Дело в том, что не оставляйте систему на усмотрение оболочки, всегда указывайте нужную оболочку в первой строке.

Гуру
источник
1
да, может быть моя текущая оболочка вызывает оболочку по умолчанию для сценария оболочки, не имеющего магических чисел.
user1678213
1
@ user1678213 Да, это делает ваша оболочка (а не ядро).
Жиль "ТАК ... перестать быть злым"
1
Я считаю, что POSIX обязывает использовать / bin / sh в этом случае.
vonbrand
2
@vonbrand Это распространенное заблуждение. POSIX не требует, чтобы POSIX-оболочка была /bin/shпросто для того, чтобы быть первым shисполняемым файлом, найденным при изучении соответствующей переменной PATH.
Jlliagre
3
Это неверно, это никогда не «оболочка входа в систему», которая используется для его выполнения. Однако может случиться так, что вызывающая оболочка (если скрипт вызывается из оболочки) может иметь дочерний элемент, который ее интерпретирует.
Стефан Шазелас
8

Когда вы запускаете программу, ядро ​​проверяет, запускается ли она какой-нибудь магической байтовой последовательностью . Если исполняемый файл начинается с #!, ядро ​​интерпретирует остальную часть строки как имя интерпретатора. Если исполняемый файл начинается с \177ELF(где \177байт 127), он загружает файл как исполняемый файл ELF ; это нормальный вид на большинстве систем Unix в настоящее время.

Если ядро ​​не распознает формат файла, оно отказывается выполнить файл и возвращает ошибку ENOEXEC (ошибка формата Exec). Когда оболочка замечает это, она берет на себя выполнение программы в виде сценария оболочки.

Чтобы убедиться в этом, добавьте несколько команд в ваш скрипт:

ps l $$
ls -l /proc/$$/exe
echo hello

(Это для Linux, настройте для других юнитов.) Затем попробуйте запустить этот скрипт из различных оболочек. Вы увидите, что некоторые оболочки порождают новые экземпляры для выполнения скрипта (bash, ksh93), в то время как другие порождают /bin/sh(dash, pdksh, zsh).

Жиль "ТАК - перестань быть злым"
источник
Что я ищу с вашей ls -lкомандой? Это: lrwxrwxrwx 1 i 0 Oct 11 05:15 exe -> /bin/bash-? Если так, что это говорит? Кроме того , заметил , что я есть SHELL=/bin/bashна env, но изменить это , похоже, не поведение изменений. Может быть, это не связано?
Эмануэль Берг
похоже, что вы меняете переменную оболочки "SHELL". Если да, то вы просто изменяете значение переменной SHELL.it, не изменяя вашу оболочку. Для изменения вашей оболочки отредактируйте файл / etc / passwd.
user1678213
2
@EmanuelBerg Да ( ls -l /proc/$$/exeна самом деле я должен был написать ). В exeссылки указывает на оболочку , которая исполняющего свой сценарий. Когда вы запустите свой скрипт, вы увидите, что bash интерпретирует скрипт. Если вы запустите его, например, из pdksh, он запустится /bin/sh. Я не знаю ни одной оболочки, которая использует SHELLпеременную окружения или оболочку входа в систему при таких обстоятельствах.
Жиль "ТАК - перестань быть злым"
2
@ user1678213 Изменение оболочки в зависимости от /etc/passwdтого, какая оболочка запускается при входе через SSH или в текстовой консоли. Это не меняет, какая оболочка может выполнять сценарии.
Жиль "ТАК - перестань быть злым"
2
@ user1678213 Я проверил то, что написал здесь, запустив тесты. Ни одна из оболочек, которые я тестировал, не смотрела, /etc/passwdчтобы решить, какую оболочку использовать, они либо раздвоили экземпляр себя, либо выполнили /bin/sh.
Жиль "ТАК - перестань быть злым"
-2

Вероятно, это одна из следующих 3 возможностей:

  1. Вы вызываете скрипт напрямую с помощью интерпретатора, т.е. IE: bash script.sh

  2. Имя файла сценария имеет расширение .sh, которое заставляет систему искать программу по умолчанию для этого типа файла.

  3. Среда оболочки, которую вы используете, выполняет 'echo' сама по себе, так как я могу только догадываться, что файл сценария является исполняемым. Например, если вы будете использовать оболочку bash и в своем файле есть команда, которую использует только ksh, то вы увидите, что она не будет работать.

Удачи!

bizna
источник
3
ни я не назвал это ни Bash, ни с каким-либо расширением.
user1678213
1
и оболочка не выполняет его, потому что когда я вызываю команду ps после вызова моего скрипта. Команда ps показывает два процесса bash. Это означает, что работают два bash. одна - моя оболочка bash для входа в систему, а другая - bash для моего basic_script
user1678213
1
2: ядро ​​не будет делать ничего подобного. Zsh может сделать это, и bash может быть превращен в это. 3: Да, но это немного изменяется между раковинами, см. Мой ответ.
Жиль "ТАК ... перестать быть злым"