Linux, macOS и Windows: устройство и переносимость

macOS — не Linux. Linux — ядро, Ubuntu — дистрибутив на его основе. macOS использует Darwin/XNU и Unix-интерфейсы, Windows — семейство NT. Похожие команды помогают переносить навыки, но не гарантируют одинаковые флаги, службы, права и двоичные форматы.

Архитектура в одной таблице

Слой Ubuntu / Linux macOS Windows
Ядро Linux, обычно описывается как монолитное с модулями XNU, сочетает Mach и BSD-компоненты NT, ядро/Executive, драйверы, HAL
Пользовательские интерфейсы libc, POSIX-подобные API, системные вызовы Linux libSystem, POSIX/Unix API и Apple frameworks Win32, .NET и NT-интерфейсы
Shell курса Bash Обычно zsh; Bash для скриптов PowerShell; Bash внутри WSL2
Управление службами systemd в Ubuntu launchd Service Control Manager; отдельный systemd внутри WSL2
Файловая система Часто ext4, но возможны другие Обычно APFS; режим регистра зависит от тома Обычно NTFS; поведение регистра имеет настройки
Домашняя папка /home/имя /Users/имя C:\Users\имя; в WSL /home/имя
Пакеты курса apt для ОС, pip в venv Python.org; Homebrew при выбранной установке Установщики/winget; apt внутри WSL
Linux-контейнеры Engine использует Linux-ядро хоста Docker Desktop использует Linux-VM Docker Desktop использует Linux-среду, в курсе WSL2

Схема упрощена для обучения: у каждой ОС больше подсистем и правил безопасности. Тип ядра не является рейтингом качества ОС и не объясняет сам по себе производительность конкретного сервиса.

Что происходит при чтении файла

Python вызывает функцию чтения. Библиотека и системный интерфейс передают запрос ядру. Ядро проверяет доступ и обращается к файловой системе/устройству. Результат возвращается приложению. Роль одинакова, но API, драйверы и формат исполняемого файла отличаются: ELF в Linux, Mach-O в macOS, PE в Windows. Один скрипт Python часто переносим; произвольный бинарник Linux напрямую на macOS не запускается.

Аналогия: пользователь делает одинаковый заказ в трёх ресторанах, но кухни устроены по-разному. Граница аналогии: одинаковое название блюда не гарантирует совпадение интерфейсов и результата во всех деталях.

Где живёт WSL2

Windows-приложение использует NT. WSL2 запускает настоящее Linux-ядро в управляемой виртуальной среде, где Ubuntu имеет собственные процессы и дерево файлов. Это не переименование PowerShell в Bash. Доступ к Windows-диску через /mnt/c связывает две среды; работа с Linux-репозиторием в /home уменьшает проблемы производительности и семантики файлов.

Docker Desktop на Mac также предоставляет Linux-среду для Linux-контейнеров. Команда docker в Terminal — клиент; процессы контейнера работают на Linux-ядре VM, не XNU. На Ubuntu Engine может использовать ядро самой системы. В каждом случае localhost относится к конкретной сетевой среде, а публикация порта связывает контейнер и хост.

Linux → macOS → Windows

Команды Windows ниже выполняются в PowerShell; Linux-команды в Windows выполняются внутри Ubuntu WSL2. Windows-аналоги не заменяют обязательную практику Bash.

Задача Ubuntu macOS PowerShell
ОС / ядро cat /etc/os-release; uname -r sw_vers; uname -r Get-CimInstance Win32_OperatingSystem
CPU-архитектура uname -m uname -m $env:PROCESSOR_ARCHITECTURE
Текущая папка pwd pwd Get-Location
Список файлов ls -lah ls -lah Get-ChildItem -Force
Содержание файла cat file.txt cat file.txt Get-Content file.txt
Поиск текста grep -n -F ERROR file.txt grep -n -F ERROR file.txt Select-String -SimpleMatch ERROR file.txt
Права ls -l; chmod 640 ls -le; chmod 640 Get-Acl file.txt; icacls file.txt
Процессы ps; top ps; Activity Monitor Get-Process
Память free -h vm_stat; Activity Monitor Get-CimInstance Win32_OperatingSystem
Диск df -h; du -sh dir df -h; du -sh dir Get-PSDrive -PSProvider FileSystem
Слушающий порт ss -ltnp lsof -nP -iTCP:8000 -sTCP:LISTEN Get-NetTCPConnection -LocalPort 8000 -State Listen
DNS getent hosts example.com dscacheutil -q host -a name example.com Resolve-DnsName example.com
HTTP curl -i URL curl -i URL curl.exe -i URL
SHA-256 sha256sum file shasum -a 256 file Get-FileHash -Algorithm SHA256 file
Службы systemctl --user launchctl Get-Service
Журнал службы journalctl --user -u NAME stdout-файл/Console/unified log по настройке Event Viewer/Get-WinEvent по источнику

PowerShell часто передаёт объекты по конвейеру, Bash/zsh в этих упражнениях — текстовые потоки. Поэтому Get-Process | ... не является текстовой копией ps | .... В Windows PowerShell имя curl может быть alias, поэтому curl.exe явно вызывает программу. macOS использует BSD-варианты многих утилит: Linux stat -c, sed -i и find -maxdepth не переносите без проверки.

Python и Git на Mac

  1. Установите поддерживаемый Python из python.org. Если уже пользуетесь Homebrew, допустим brew install python git; курс не требует установки нового пакетного менеджера.
  2. Проверьте python3 --version, git --version, bash --version.
  3. Скопируйте lab в ~/devops-course/lab, создайте .venv и запустите .venv/bin/python app.py.
  4. Команды Git, curl и Docker из курса в основном совпадают; рядом с каждым занятием дан Mac-вариант.

Для уроков systemd используйте Ubuntu VM, например выбранный вузом гипервизор, либо WSL2 рабочего места партнёра. На Apple Silicon Ubuntu VM должна иметь подходящую архитектуру. Не пытайтесь запускать systemctl непосредственно на macOS.

launchd: необязательная демонстрация

Если преподаватель хочет показать тот же принцип службы на Mac, используйте пользовательский LaunchAgent, без системных демонов. Сохраните ниже ~/Library/LaunchAgents/cloud.zorin.studypulse.plist, заменив все /Users/YOUR_NAME реальным абсолютным домашним путём:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>cloud.zorin.studypulse</string>
  <key>ProgramArguments</key><array>
    <string>/Users/YOUR_NAME/devops-course/lab/.venv/bin/python</string>
    <string>/Users/YOUR_NAME/devops-course/lab/app.py</string>
  </array>
  <key>WorkingDirectory</key><string>/Users/YOUR_NAME/devops-course/lab</string>
  <key>RunAtLoad</key><true/>
  <key>EnvironmentVariables</key><dict>
    <key>HOST</key><string>127.0.0.1</string>
    <key>PORT</key><string>8000</string>
  </dict>
  <key>StandardOutPath</key><string>/Users/YOUR_NAME/devops-course/lab/launchd.log</string>
  <key>StandardErrorPath</key><string>/Users/YOUR_NAME/devops-course/lab/launchd-error.log</string>
</dict></plist>

Остановите прежний ручной запуск, затем:

plutil -lint ~/Library/LaunchAgents/cloud.zorin.studypulse.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/cloud.zorin.studypulse.plist
launchctl print gui/$(id -u)/cloud.zorin.studypulse
curl -i http://127.0.0.1:8000/healthz
launchctl bootout gui/$(id -u)/cloud.zorin.studypulse

bootstrap может сообщить, что агент уже загружен: сначала изучите print, не создавайте дубликаты. В примере нет KeepAlive, чтобы ошибочная конфигурация не создала бесконечный цикл рестартов. Файлы stdout/stderr — отдельная настройка этого агента, не автоматический аналог всего journalctl. Пример сверён с документацией, но в этой подготовке не исполнен на реальном Mac; преподаватель проверяет его до показа.

ARM64 и AMD64

uname -m показывает архитектуру текущей среды. Apple Silicon обычно ARM64, многие Linux-серверы — AMD64. Dockerfile может быть одинаковым, но собранный образ должен поддерживать архитектуру целевого узла. Тег multi-platform образа ссылается на варианты; обычный локальный образ может содержать только один.

Для доставки на AMD64 можно использовать целевой build docker build --platform linux/amd64 -t studypulse:amd64 .; на ARM он может потребовать эмуляции и быть медленнее. Для нескольких платформ применяют buildx и подходящее хранилище образов. На занятии достаточно понять проблему и записать архитектуру в release-report. Проверка на ARM не доказывает, что AMD64-вариант испытан.

Источники

Apple: XNU, Apple: launchd, Microsoft: WSL1/WSL2, Docker Desktop Mac, Docker multi-platform.