Як оболонка виконує програму?


11

Якщо я компілюю програму за допомогою gcc і намагаюся виконати її з оболонки bash, то яка точна послідовність кроків, за якими слід bash, щоб виконати її?

Я знаю fork(), execve(), loader, dynamic linker(і інші речі) бере участь, але може хто - то дати точну послідовність кроків , і деякі відповідні посилання для читання?

Редагувати:

З відповідей, мабуть, питання може припускати багато можливостей. Я хочу звузитися до простого випадку:

(test.c просто друкує привіт світ)

$ gcc test.c -o test
$ ./test

Які будуть кроки у наведеному вище випадку ( ./test), зокрема стосовно програми запуску bash в якомусь дочірньому процесі, роблячи завантаження, зв'язування тощо?


4
Запрошую вас прочитати lwn.net/Articles/630727
cuonglm

3
Чому б не спробувати тест `strace bash -c '?
Сергій Колодяжний

2
Здається, що гідний підручник з операційних систем був би хорошим ресурсом для ОП. Спроба дізнатися, як працюють операційні системи, задаючи подібні питання, мабуть, не буде результативним процесом.
Бармар

Було б корисно побачити мінімальний приклад оболонки: brennan.io/2015/01/16/write-a-shell-in-c
jinawee

Відповіді:


5

Ну, точна послідовність може змінюватися, оскільки може бути псевдонім оболонки або функція, яка спочатку розширюється / інтерпретується до того, як реальна програма буде виконана, а потім відмінності для кваліфікованого імені файлу ( /usr/libexec/foo) порівняно з тим, що шукатиметься у всіх каталогах з PATHзмінної оточення (тільки foo). Крім того , деталі виконання можуть ускладнити ситуацію, оскільки foo | bar | zotвимагає більше роботи для оболонки (кілька fork(2), dup(2)і, звичайно ж , pipe(2)серед інших системних викликів), в той час як що - щось на зразок exec fooнабагато менше роботи , як оболонка просто замінює себе нова програма (тобто її немає fork). Важливими також є групи процесів (особливо група переднього плану, всі ПІД яких харчуються)SIGINTколи хтось починає масувати на Ctrl+ C, сеанси, а також чи буде робота виконуватись у фоновому режимі, відслідковується ( foo &) або фон, ігнорується ( foo & disown). Деталі переадресації вводу / виводу також змінять речі, наприклад, якщо стандартний вхід закритий оболонкою ( foo <&-) або відкрито файл як stdin ( foo < blah).

straceабо подібні будуть інформативними щодо конкретних системних дзвінків, здійснених в ході цього процесу, і для кожного з цих викликів повинні бути довідкові сторінки. Прийнятним для читання на рівні системи буде будь-яка кількість глав з "Розширеного програмування Стівенса в середовищі UNIX", тоді як книга оболонок (наприклад, "Від Баша до Z Шелла") більш детально висвітлює сторону оболонки.


Я редагував питання, щоб звузити до простого випадку
Джейк

1

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

  • read: отримує наступну команду в цьому випадку gcc
  • вилка: потрібні два процеси, ми припускаємо, що батько має pid 500, а дитина для ілюстрації.
  • батько зателефонує зачекати (501), тим часом дитина зателефонує до exec. У цей момент оболонка більше не працює на pid 501. gcc здійснює безліч системних дзвінків, включаючи мінімум відкриття, закриття, зчитування, запис, chmod, fork, exec, очікування та вихід.
  • коли gcc викликає вихід, чекання повернеться, запит викликається, щоб відобразити підказку, і процес повториться.

Більш складні команди, звичайно, додають більшої складності цій базовій послідовності. Два простіші приклади основних ускладнень - це базове перенаправлення io, де послідовність відкритого, закритого та повторного копіювання вставляється між вилкою та exec та фоновими процесами, де очікування пропускається (і ще одне очікування додається до обробника sigchld).


Невелике доповнення: запитання задає питання про завантаження та динамічне посилання. Весь код, який є статично пов'язаним, тобто фактично включений у файл програми, виконується ядром до запуску програми. Динамічно завантажені бібліотеки, тобто окремі файли, обробляються самою програмою перед запуском main (). Код для цього автоматично додається gcc.
Стиг Хеммер

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.