Unix-подобные системы: Linux, BSD, macOS, POSIX и общие принципы

Unix-подобные системы: Linux, BSD, macOS, POSIX и общие принципы Полезное

Unix-подобная система — это операционная система, которая устроена и ведет себя как Unix: многозадачная и многопользовательская, с иерархической файловой системой от корня /, процессами, правами доступа и командной оболочкой. Сегодня к этому семейству относятся Linux, системы BSD (FreeBSD, OpenBSD, NetBSD) и macOS. Ниже разберем, чем они отличаются, что их объединяет и как это увидеть в терминале.

Unix, UNIX и Unix-подобные: три разных понятия

Слово «Unix» употребляют в трех смыслах, и их полезно развести сразу.

Термин Что означает Пример
Unix (исторический) исходная система Bell Labs 1970-х и ее прямые потомки Research Unix, System V
UNIX (торговая марка) система, прошедшая сертификацию The Open Group на соответствие Single UNIX Specification macOS, IBM AIX, HP-UX
Unix-подобная (Unix-like) ведет себя как Unix, но не обязательно сертифицирована и не содержит исходного кода Unix большинство дистрибутивов Linux, FreeBSD

Linux не произошел от кода Unix: ядро написано заново, поэтому Linux — Unix-подобная система, а не «версия Unix». При этом macOS формально сертифицирована как UNIX. История самой Unix — отдельная тема, здесь речь о семействе в нынешнем виде.

POSIX: что на самом деле общее у семейства

POSIX (Portable Operating System Interface) — стандарт IEEE, который описывает программный интерфейс системы (системные вызовы и функции C), поведение оболочки sh и набор базовых утилит. Актуальная редакция — POSIX.1-2024.

Практический смысл простой: скрипт или программа, написанные строго по POSIX, запустятся на Linux, FreeBSD и macOS без переделки. Граница этого правила важна:

  • POSIX не описывает графический интерфейс, менеджеры пакетов, систему инициализации и сетевую настройку — здесь системы расходятся сильнее всего;
  • утилиты часто имеют расширения сверх стандарта: GNU sed в Linux и BSD sed в macOS по-разному понимают sed -i;
  • соответствие стандарту на практике бывает «в основном», а сертификация — отдельная платная процедура.

Поэтому формулировка «работает на любом Unix» верна только для кода, который не выходит за рамки POSIX.

Сравнение Linux, BSD и macOS

Признак Linux FreeBSD macOS
Что это ядро + дистрибутивы (Ubuntu, Debian, Fedora, RHEL и другие) цельная ОС: ядро и базовая система в одном репозитории ОС Apple на ядре XNU (Mach + части BSD)
Лицензия ядра GPLv2 BSD ядро XNU открыто, система в целом проприетарная
Сертификат UNIX как правило, нет нет есть
Первый процесс (PID 1) обычно systemd init + скрипты rc launchd
Установка программ apt, dnf и другие, зависит от дистрибутива pkg и дерево портов App Store, сторонний Homebrew
Где встречается серверы, облака, контейнеры, суперкомпьютеры, встраиваемые устройства серверы, сетевые устройства, хранилища ноутбуки и рабочие станции разработчиков

Как выбрать под задачу:

  • учиться администрированию и работать с серверами — Linux: на нем работает основная часть облачных серверов и почти все контейнеры;
  • нужна цельная система с единой базой и документацией — FreeBSD, например для сетевых и файловых серверов;
  • разработка на ноутбуке — macOS дает Unix-терминал и графическую среду, но серверное окружение все равно лучше повторять в Linux (в виртуальной машине или контейнере).

Android использует ядро Linux, но пользовательское окружение у него другое, поэтому в разговоре об администрировании его обычно не относят к «Linux-системам».

Философия Unix: маленькие программы и конвейеры

Идею семейства часто формулируют словами Дуга Макилроя: пишите программы, которые делают одну вещь и делают ее хорошо; пишите программы, которые работают вместе; используйте текстовые потоки как универсальный интерфейс.

На практике это конвейер (pipe, символ |): вывод одной команды становится входом следующей. Пример ниже создает файл со списком процессов и считает уникальные имена. Он запускается в любой Unix-подобной системе.

printf 'nginx\nsshd\nnginx\ncron\nnginx\n' > procs.txt
sort procs.txt | uniq | tr '\n' ' '; echo
grep -c nginx procs.txt

Результат:

cron nginx sshd 
3

Разбор: sort упорядочивает строки, uniq убирает соседние повторы (поэтому ему нужен отсортированный вход), tr склеивает строки через пробел, grep -c считает совпадения. Утилиты не знают друг о друге — их связывает только текстовый поток. Упрощение: современные инструменты часто обмениваются JSON или двоичными данными, но принцип компоновки остался.

Процессы: как система выполняет программы

Процесс — это запущенная программа со своим номером PID, памятью и правами. Процессы образуют дерево: каждый, кроме первого, запущен родителем (PPID). Первый процесс с PID 1 запускает ядро, а он уже поднимает службы — в большинстве дистрибутивов Linux это systemd, в macOS — launchd.

Новый процесс в Unix появляется в два шага: системный вызов fork() создает копию родителя, затем exec() заменяет в копии программу. Оболочка делает это при каждом запуске команды.

У каждого завершившегося процесса есть код возврата: 0 означает успех, любое другое число — ошибку. На этом строятся условия в скриптах.

printf 'nginx\nsshd\ncron\n' > procs.txt
grep -q nginx procs.txt; echo "nginx: код $?"
grep -q apache procs.txt; echo "apache: код $?"
sleep 30 &
pid=$!
kill "$pid"
wait "$pid"; echo "sleep завершен с кодом $?"

Результат:

nginx: код 0
apache: код 1
sleep завершен с кодом 143

Кроме этого, bash может напечатать в поток ошибок служебную строку Terminated про фоновое задание. Код 143 — это 128 + 15: процесс остановлен сигналом SIGTERM (номер 15), который по умолчанию отправляет kill. SIGTERM просит программу завершиться штатно и дает ей закрыть файлы. SIGKILL (kill -9) убивает процесс без шанса на уборку, поэтому его применяют только если процесс не реагирует на SIGTERM.

Службы, работающие в фоне без терминала, называют демонами (daemons): sshd, cron, nginx. Буква «d» в конце имени — традиция, а не правило.

Пользователи и права доступа

Unix изначально многопользовательская система, поэтому у каждого файла есть владелец, группа и три набора прав: для владельца (u), группы (g) и остальных (o). Каждый набор — это чтение (r), запись (w) и выполнение (x).

Права удобно записывать числом: r = 4, w = 2, x = 1, сумма по каждой тройке. Например, 640 — владелец читает и пишет, группа только читает, остальным доступа нет.

Пример ниже работает в отдельном каталоге demo, чтобы не задеть чужие файлы:

mkdir -p demo && cd demo
echo "api_key=test" > app.conf
chmod 640 app.conf
ls -l app.conf | cut -c1-10
chmod 200 app.conf
cat app.conf 2>/dev/null || echo "чтение запрещено"
chmod 640 app.conf
cat app.conf

Результат для обычного пользователя:

-rw-r-----
чтение запрещено
api_key=test

После chmod 200 у владельца осталась только запись, и cat получает отказ (Permission denied); возврат к 640 снова разрешает чтение. Граница примера: root (UID 0) обходит проверки чтения и записи, и под ним вторая строка покажет содержимое файла. Поэтому работают под обычной учетной записью, а админские команды выполняют через sudo точечно.

Правила безопасности, которые стоит усвоить сразу:

  • файлам с секретами (ключи, пароли, конфиги с токенами) давать 600 или 640, а не 644 и тем более 777;
  • не применять chmod -R ко всему каталогу одним режимом: каталогам нужен бит x для входа, обычным файлам он не нужен, их разделяют через find -type d и find -type f;
  • перед массовой сменой прав или владельца на сервере проверять команду на копии и держать вторую открытую сессию, чтобы не потерять доступ.

«Все есть файл»: что это значит на практике

Принцип «все есть файл» означает, что многие ресурсы доступны через файловые пути и одни и те же операции чтения и записи. Устройства лежат в /dev, а в Linux сведения о процессах и ядре видны как файлы в /proc и /sys.

echo "этот текст исчезнет" > /dev/null
head -c 8 /dev/urandom | wc -c | tr -d ' '

Первая команда пишет в «черную дыру» /dev/null и ничего не выводит. Вторая читает 8 случайных байт из /dev/urandom и печатает их количество: 8.

Это упрощение: сетевые соединения и процессы не являются файлами на диске, но работают через похожий интерфейс файловых дескрипторов. /proc устроен по-разному: в Linux он подробный, в FreeBSD по умолчанию не смонтирован, в macOS его нет.

Как попробовать Unix-подобную систему

  1. Выбрать среду: на Windows — WSL 2 с Ubuntu, на macOS — встроенный Терминал, в любом случае — виртуальная машина с Debian или Ubuntu Server.
  2. Выяснить, где вы: uname -s выведет Linux, Darwin (macOS) или FreeBSD.
  3. Повторить примеры этой статьи в отдельном каталоге.
  4. Итоговый артефакт — короткий скрипт, который считает самые частые процессы через ps, sort и uniq и пишет отчет в файл с правами 640.

Если не получилось:

  • Permission denied при запуске скрипта — у файла нет бита выполнения: chmod u+x script.sh или запуск через bash script.sh;
  • command not found — утилиты нет в системе или ее каталога нет в PATH, проверить через command -v имя;
  • команда ведет себя иначе, чем в инструкции — скорее всего, разница GNU и BSD-версий утилит, смотрите man имя на своей системе.

Выводы

  • Unix-подобные системы — семейство с общими принципами: процессы, иерархия файлов от /, права пользователей, оболочка и маленькие утилиты.
  • «UNIX» с сертификатом и «Unix-подобная» — разные вещи: macOS сертифицирована, Linux и FreeBSD, как правило, нет, но ведут себя по-юниксовому.
  • Общий знаменатель задает POSIX: код в его рамках переносим, а пакеты, init и GUI у систем разные.
  • Для серверов и администрирования основная среда — Linux; FreeBSD и macOS полезно знать как соседей по семейству.
  • Права 640/600 для секретов и отказ от массового chmod -R — базовая гигиена на любой Unix-системе.

Где применяется / связь с практикой

Знание общих принципов Unix нужно всем, кто работает с серверами: администраторам, DevOps-инженерам, бэкенд-разработчикам и тестировщикам, которые разбирают логи. Самая частая точка входа — Linux, потому что на нем работает основная часть серверов и контейнеров.

Освойте тему на практике

Системно освоить командную строку, процессы, права и службы можно на курсе «Linux. Базовый». Чтобы оценить формат занятий, загляните на бесплатные открытые уроки Otus.

FAQ

Можно ли запускать программы для Linux на macOS или FreeBSD?
Исходный код в рамках POSIX обычно собирается на всех трех системах, а готовые бинарные файлы Linux напрямую на macOS не запускаются. FreeBSD умеет выполнять часть Linux-программ через слой совместимости Linuxulator.

Чем bash отличается от sh и zsh?
sh — оболочка, поведение которой описано в POSIX; bash и zsh — ее расширенные варианты с дополнительным синтаксисом. В macOS оболочкой по умолчанию давно стоит zsh, в большинстве дистрибутивов Linux — bash, поэтому переносимые скрипты пишут под sh.

Windows стала Unix-подобной, раз в ней есть WSL?
Нет. WSL 2 запускает настоящее ядро Linux в легкой виртуальной машине рядом с Windows, но сама Windows остается системой другого устройства.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)