сценарії оболонки досі працюють без #! (рядок sha-bang)


10

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

тому мої запитання:

  • звідки мій базовий сценарій взяв перекладача.
  • як сценарію вдалося знайти перекладача.

тепер дозвольте мені розповісти вам про мій базовий сценарій, він просто містить такий рядок:

відлуння "базовий сценарій без магічних рядків"


Відповіді:


3

Якщо магічна лінія не передбачена, для запуску сценарію використовується оболонка за замовчуванням. Ця оболонка за замовчуванням може бути або оболонкою Bourne (sh), що є випадком у деяких ароматизаторах, однак у деяких інших ароматах оболонка за замовчуванням, яка використовується для її виконання, є такою ж, як оболонка для входу. Річ у тому, що: не залишайте це системі для вирішення оболонки, завжди надайте оболонку, яку ви хочете, у першому рядку.


1
yup..може моя поточна оболонка викликає стандартну оболонку для сценарію оболонки, не маючи магічних чисел.
user1678213

1
@ user1678213 Так, це робить ваша оболонка (а не ядро).
Жиль "ТАК - перестань бути злим"

1
Я вважаю, що POSIX наказує, що / bin / sh використовується в цьому випадку.
vonbrand

2
@vonbrand Це поширене неправильне уявлення. POSIX не зобов’язує оболонку POSIX бути /bin/sh, просто бути першим shвиконавчим файлом, знайденим під час дослідження відповідного PATH.
jlliagre

3
Це неправильно, це ніколи не "оболонка входу", яка використовується для її виконання. Що може статися, це те, що оболонка виклику (якщо сценарій викликається з оболонки) може мати дитину, яка сама інтерпретує її.
Stéphane Chazelas

8

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

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

Щоб засвідчити це в дії, додайте до свого сценарію кілька команд:

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

(Це для Linux, налаштуйте для інших unice.) Потім спробуйте запустити цей скрипт з різних оболонок. Ви побачите, що деякі оболонки породжують нові екземпляри себе для виконання сценарію (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 не будете змінювати свою оболонку.
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. Середовище оболонки, яке ви використовуєте, виконує «відлуння» само собою, оскільки я можу лише здогадуватися, що файл сценарію виконується. Якщо, наприклад, ви будете використовувати оболонку bash і матимуть у своєму файлі команду, яка використовується тільки ksh, ви побачите, що вона не працюватиме.

Удачі!


3
ні я не називав це басом, ні будь-яким розширенням.
user1678213

1
і середовище оболонки не виконує його, тому що коли я викликаю команду ps після виклику мого сценарію. Команда ps показує два bash process. що означає, що є два bash run. один - моя оболонка bash bash, а другий - bash для мого basic_script
user1678213

1
2: ядро ​​нічого подібного не зробить. Zsh може це зробити, і bash можна скрутити, щоб це зробити. 3: Так, але це залежно від снарядів, дивіться мою відповідь.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.