Unix, Linux, дистрибутиви
Навіщо це
Section titled “Навіщо це”Linux, macOS і Android — три різні системи, які поводяться підозріло схоже.
Ті самі fork і exec, ті самі права rwx, ті самі конвеєри. При цьому
спільного коду між ними майже немає.
Розбиратися, звідки взялася ця схожість, варто не з історичного інтересу.
Це пояснює цілком практичні речі: чому програма збирається на одній системі
й не збирається на іншій, чому Apple взяла код BSD, а не Linux, і чому ls
на вашій машині може виявитися трьома різними програмами.
Unix: 1969
Section titled “Unix: 1969”Multics, спільний проєкт MIT, Bell Labs і General Electric, мав стати системою поділу часу для сотень користувачів. Він розростався, запізнювався, і врешті Bell Labs із проєкту вийшла.
Кен Томпсон і Денніс Рітчі почали писати щось радикально простіше. Назва Unics була жартом над Multics: той робив складно і для всіх, а цей просто і для кількох.
У 1973-му ухвалили рішення, яке все й визначило: ядро переписали на C. Доти ядра писали асемблером, і кожне було прив’язане до однієї моделі машини. Ядро мовою високого рівня вдалося перенести на іншу архітектуру, і саме переносимість, а не витонченість дизайну, зробила Unix основою всього, що прийшло потім.
Філософія Unix виросла з обмежень тодішнього заліза, але пережила їх: маленькі програми, що добре роблять одну річ, текст як універсальний інтерфейс між ними, композиція замість монолітів, усе представлене файлом.
Розкол
Section titled “Розкол”З сімдесятих Unix розійшовся на дві гілки. System V була комерційною лінією AT&T, а BSD — розробкою Берклі, яка додала мережевий стек TCP/IP, сокети й віртуальну пам’ять. Чимало з того, чим користуються сьогодні, прийшло саме звідти.
У 1983-му Річард Столмен почав GNU, проєкт зі створення повністю вільного Unix-сумісного набору програм. На початок дев’яностих GNU мав компілятор, оболонку, бібліотеку C і сотні утиліт, але не мав робочого ядра.
Ядро написав у 1991-му Лінус Торвальдс. Коду Unix у ньому не було жодного рядка: це була незалежна реалізація тих самих інтерфейсів.
Ліцензія як технічне рішення
Section titled “Ліцензія як технічне рішення”Долю систем ліцензія визначила не менше, ніж якість коду.
GPL, під якою вийшли Linux і GNU, вимагає відкривати зміни, якщо ви їх розповсюджуєте. Через це в Linux потекли вклади компаній, які не могли тримати свої правки закритими, і ядро стало спільним активом конкурентів.
BSD-ліцензія, навпаки, дозволяє брати код у закриті продукти без жодних зобов’язань. Тому мережевий стек BSD опинився всюди, а Apple побудувала macOS на основі BSD і Mach: узяти Linux означало б відкрити систему.
З тієї ж причини Android бере ядро Linux, бо GPL стосується ядра і зміни
до нього відкриті, але GNU не бере: замість glibc там Bionic
під BSD-ліцензією, та й решта простору користувача не є GPL.
З чого складається дистрибутив
Section titled “З чого складається дистрибутив”Ядро саме по собі нічого не робить, у нього немає ні оболонки, ні утиліт. Дистрибутивом називають ядро плюс усе інше.
| Складова | Приклади | Роль |
|---|---|---|
| Ядро | Linux | процеси, пам’ять, ФС, драйвери |
| Бібліотека C | glibc, musl, Bionic | обгортки над системними викликами |
| Система ініціалізації | systemd, OpenRC, runit | PID 1, запуск служб |
| Базові утиліти | GNU coreutils, BusyBox | ls, cp, cat |
| Оболонка | bash, zsh, ash | інтерфейс командного рядка |
| Менеджер пакетів | apt, dnf, pacman, apk | встановлення й оновлення |
Замініть будь-який рядок цієї таблиці — отримаєте іншу систему.
Alpine Linux бере musl замість glibc і BusyBox замість coreutils,
через що образ виходить у десятки разів меншим, зате програми, зібрані
під glibc, там просто не запускаються. Це, до речі, найчастіша причина
славнозвісного «у Docker не працює, а локально працює».
Родини
Section titled “Родини”Debian і похідні (Ubuntu, Mint) використовують apt і формат .deb,
а роблять ставку на стабільність і величезний репозиторій.
Red Hat і похідні (RHEL, Fedora, Rocky) — це dnf і формат .rpm,
де Fedora слугує полігоном для того, що згодом потрапляє в RHEL.
Arch віддає пакети одразу після релізу, а систему користувач збирає собі сам із мінімуму.
Alpine побудований на musl і BusyBox заради мінімального розміру
й став через це стандартом для контейнерів.
NixOS описує конфігурацію системи декларативно, тому оновлення відкочується цілком.
Сусіди
Section titled “Сусіди”macOS є сертифікованим UNIX. Ядро XNU поєднує мікроядро Mach і підсистему BSD, а простір користувача походить від BSD, не від GNU.
Android використовує ядро Linux зі значними змінами: wakelocks,
Binder для міжпроцесного зв’язку, окрема модель дозволів. Замість glibc
там Bionic, а замість звичного набору утиліт — середовище виконання ART.
WSL2 запускає справжнє ядро Linux у полегшеній віртуальній машині поверх Hyper-V. Перша версія WSL пробувала транслювати системні виклики Linux у виклики Windows і наштовхнулася рівно на те, про що йшлося в модулі 3: відтворити чуже ABI повністю неймовірно важко.
Як це насправді в Linux
Section titled “Як це насправді в Linux”uname -r; cat /etc/os-release | head -3Версія ядра і версія дистрибутива — незалежні числа. Одне ядро працює під десятками дистрибутивів.
ldd --version | head -1; ldd /bin/lsЯка бібліотека C використовується і з чим злінковано ls.
На Alpine ці команди дадуть зовсім інший результат.
readlink -f /bin/shКуди насправді вказує /bin/sh. У Debian це dash, а не bash —
і скрипт із #!/bin/sh, який використовує розширення bash, зламається.
ls /usr/bin | wc -l; dpkg -S /bin/ls 2>/dev/null || rpm -qf /bin/ls 2>/dev/nullСкільки програм у системі і з якого пакета прийшла конкретна. Ядро не має до жодної з них стосунку.
ps -p 1 -o comm=Що працює як PID 1 — systemd, init чи щось інше
(модуль 5).
getconf _POSIX_VERSIONВерсія POSIX, якої дотримується система.
Типові помилки розуміння
Section titled “Типові помилки розуміння”«Linux — це операційна система». Linux є ядром. Операційною системою буде дистрибутив: ядро плюс бібліотека C, ініціалізація, утиліти й тисячі пакетів.
«Linux походить від Unix». Спільного коду в них немає. Linux — незалежна реалізація тих самих інтерфейсів, тож спорідненість тут інтерфейсна, а не генеалогічна.
«POSIX означає, що програма запуститься скрізь». Означає, що запуститься програма, яка за межі POSIX не виходить. Більшість реального коду використовує розширення конкретної системи.
«Android — дистрибутив Linux». Ядро Linux там справді є, а GNU немає: інша бібліотека C, інше середовище виконання, інша модель дозволів.
«macOS побудований на Linux». Він побудований на BSD і Mach, а схожість команд пояснюється спільним предком, не спільним кодом.
«У контейнері не працює, бо Docker зламався». Найімовірніше, образ
зібраний на Alpine з musl, а програма — під glibc.
Перевір себе
Джерела
Section titled “Джерела”- The UNIX Time-Sharing System — Рітчі й Томпсон, 1974
- Раймонд, The Art of Unix Programming — про філософію Unix
- Айзексон, Інноватори — історія галузі як історія людей
- Nemeth та ін., UNIX and Linux System Administration Handbook
man 7 standards,getconf _POSIX_VERSION