crefft Source 2026.10.4

Operating System Fundamentals

Source index and context

crefft > Infrastructure > Operating Systems

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

Overview

This guide covers cross-platform operating system concepts. Platform-specific details are in dedicated guides:

PlatformGuidePrimary Use
Linux (Debian)linux.mdServers, containers, workstations
macOSComing soonDevelopment workstations
WindowsComing soonEnterprise, .NET, gaming

Quick Reference

ConceptLinux (systemd)macOSWindows
Service managersystemctllaunchctlsc.exe, Services MMC
Package managerapt, dnfbrewwinget, choco
Firewallnftables, ufwpfWindows Firewall
Init systemsystemdlaunchdSCM
Privilege escalationsudosudoUAC, runas
Shellbash, zshzshPowerShell, cmd
Filesystem root//C:\

Table of Contents

  1. Users and Groups
  2. Permissions
  3. Service Management
  4. Package Management
  5. Filesystem Layout
  6. Environment Variables
  7. Process Management
  8. Choosing an OS

Users and Groups

Concepts

All modern operating systems use users and groups to control access:

ConceptDescription
UserIdentity that owns processes and files
GroupCollection of users for shared permissions
Primary groupDefault group for new files
Supplementary groupsAdditional group memberships
Service accountNon-interactive user for running services

Cross-Platform Comparison

TaskLinuxmacOSWindows
Current userwhoamiwhoamiwhoami
List usersgetent passwddscl . list /UsersGet-LocalUser
Create useruseraddsysadminctl -addUserNew-LocalUser
Add to groupusermod -aG group userdseditgroup -o edit -a user -t user groupAdd-LocalGroupMember
Service accountsuseradd --systemN/A (use _name)New-LocalUser + deny logon

Best Practices

  • MUST use dedicated service accounts for each service
  • MUST NOT run services as root/Administrator unless required
  • SHOULD use descriptive names (_prometheus, svc_webapp)
  • SHOULD disable shell access for service accounts
# Linux: Create service account
useradd --system --shell /usr/sbin/nologin --home-dir /nonexistent prometheus

# Verify no shell access
getent passwd prometheus
# prometheus:x:998:998::/nonexistent:/usr/sbin/nologin

Permissions

POSIX Permissions (Linux/macOS)

-rwxr-xr-- 1 owner group 4096 Jan 1 12:00 file.txt
│└┬┘└┬┘└┬┘
│ │  │  └── Other: read only
│ │  └───── Group: read + execute
│ └──────── Owner: read + write + execute
└────────── File type (- = file, d = directory, l = symlink)
PermissionFilesDirectories
Read (r/4)View contentsList contents
Write (w/2)Modify contentsCreate/delete files
Execute (x/1)Run as programEnter directory

Special Permissions

PermissionOctalEffect
setuid4000Run as file owner
setgid2000Run as file group / inherit group in dirs
sticky1000Only owner can delete (used on /tmp)

Standard Permission Patterns

Use CaseOctalSymbolicExample
Private file0600rw-------SSH private keys
Private directory0700rwx------~/.ssh
Config file0644rw-r--r--/etc/app.conf
Executable0755rwxr-xr-x/usr/bin/app
Shared directory2775rwxrwsr-x/var/www (setgid)
Temp directory1777rwxrwxrwt/tmp (sticky)

Windows Permissions

Windows uses Access Control Lists (ACLs) with more granular permissions:

PermissionDescription
Full ControlAll permissions including changing ownership
ModifyRead, write, execute, delete
Read & ExecuteView and run
ReadView only
WriteCreate and modify
# View permissions
Get-Acl C:\path\file.txt | Format-List

# Set permissions
$acl = Get-Acl C:\path
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "Users", "ReadAndExecute", "Allow")
$acl.SetAccessRule($rule)
Set-Acl C:\path $acl

Best Practices

  • MUST use 0600 for private keys and credentials
  • MUST use 0700 for directories containing secrets
  • MUST NOT use 0777 (world-writable) for any file
  • SHOULD use setgid on shared directories for consistent group ownership

Service Management

systemd (Linux)

Modern Linux distributions use systemd for service management:

# Service lifecycle
systemctl start nginx          # Start service
systemctl stop nginx           # Stop service
systemctl restart nginx        # Stop then start
systemctl reload nginx         # Reload config (if supported)
systemctl status nginx         # View status

# Enable/disable on boot
systemctl enable nginx         # Start on boot
systemctl disable nginx        # Don't start on boot
systemctl enable --now nginx   # Enable and start immediately

# View logs
journalctl -u nginx            # All logs for service
journalctl -u nginx -f         # Follow logs
journalctl -u nginx --since "1 hour ago"

launchd (macOS)

macOS uses launchd with plist configuration:

# Service lifecycle
launchctl load /Library/LaunchDaemons/com.example.app.plist
launchctl unload /Library/LaunchDaemons/com.example.app.plist
launchctl start com.example.app
launchctl stop com.example.app
launchctl list | grep example

# Locations
# /Library/LaunchDaemons/     - System-wide daemons (root)
# /Library/LaunchAgents/      - System-wide agents (user session)
# ~/Library/LaunchAgents/     - Per-user agents

Windows Services

# Service lifecycle
Start-Service -Name "nginx"
Stop-Service -Name "nginx"
Restart-Service -Name "nginx"
Get-Service -Name "nginx"

# Enable/disable
Set-Service -Name "nginx" -StartupType Automatic
Set-Service -Name "nginx" -StartupType Disabled

# Create service
New-Service -Name "MyApp" -BinaryPathName "C:\app\myapp.exe" `
    -StartupType Automatic -Description "My Application"

Best Practices

  • MUST use the native service manager (not cron/Task Scheduler for services)
  • MUST configure service dependencies correctly
  • SHOULD use socket activation where available (systemd)
  • SHOULD configure automatic restart on failure

Package Management

Comparison

Featureapt (Debian)dnf (Fedora)brew (macOS)winget (Windows)
Update indexapt updatednf check-updatebrew updatewinget upgrade
Upgrade allapt upgradednf upgradebrew upgradewinget upgrade --all
Installapt install pkgdnf install pkgbrew install pkgwinget install pkg
Removeapt remove pkgdnf remove pkgbrew uninstall pkgwinget uninstall pkg
Searchapt search pkgdnf search pkgbrew search pkgwinget search pkg
Infoapt show pkgdnf info pkgbrew info pkgwinget show pkg
List installedapt list --installeddnf list installedbrew listwinget list

Best Practices

  • MUST update package index before installing
  • MUST pin versions in automation scripts
  • SHOULD use unattended-upgrades (Linux) for security updates
  • SHOULD avoid mixing package managers (apt + snap + pip)
# Linux: Pin package version
apt install nginx=1.24.0-1

# macOS: Pin formula
brew pin nginx

# Windows: Specify version
winget install nginx --version 1.24.0

Filesystem Layout

Linux (FHS)

/
├── bin/          # Essential user binaries (often → /usr/bin)
├── boot/         # Bootloader files
├── dev/          # Device files
├── etc/          # System configuration
├── home/         # User home directories
├── lib/          # Essential libraries (often → /usr/lib)
├── mnt/          # Temporary mount points
├── opt/          # Optional/third-party software
├── proc/         # Process information (virtual)
├── root/         # Root user's home
├── run/          # Runtime data (tmpfs)
├── srv/          # Service data (web, ftp)
├── sys/          # Kernel/hardware info (virtual)
├── tmp/          # Temporary files
├── usr/          # User programs and data
│   ├── bin/      # User binaries
│   ├── lib/      # Libraries
│   ├── local/    # Locally installed software
│   └── share/    # Architecture-independent data
└── var/          # Variable data
    ├── cache/    # Application cache
    ├── lib/      # State information
    ├── log/      # Log files
    └── run/      # → /run

macOS

/
├── Applications/           # GUI applications
├── Library/               # System-wide support files
├── System/                # macOS system files (SIP protected)
├── Users/                 # User home directories
├── Volumes/               # Mounted volumes
├── bin/, etc/, usr/, var/ # BSD layer (similar to Linux)
├── opt/                   # Homebrew (Apple Silicon)
└── usr/local/             # Homebrew (Intel), local software

Windows

C:\
├── Program Files\         # 64-bit applications
├── Program Files (x86)\   # 32-bit applications
├── ProgramData\           # Application data (all users)
├── Users\                 # User profiles
│   └── <user>\
│       ├── AppData\
│       │   ├── Local\     # Non-roaming app data
│       │   ├── LocalLow\  # Low-integrity app data
│       │   └── Roaming\   # Roaming profiles
│       ├── Desktop\
│       └── Documents\
├── Windows\               # Operating system
│   ├── System32\         # System binaries (64-bit!)
│   └── SysWOW64\         # 32-bit compatibility
└── temp\                  # System temp

Environment Variables

Common Variables

VariableLinux/macOSWindowsPurpose
Home directory$HOME%USERPROFILE%User’s home
Temp directory$TMPDIR, /tmp%TEMP%Temporary files
Path$PATH%PATH%Executable search path
User$USER%USERNAME%Current username
Shell$SHELLN/ADefault shell
Editor$EDITORN/ADefault text editor

Setting Variables

# Linux/macOS - Session
export MY_VAR="value"

# Linux/macOS - Persistent (add to ~/.bashrc, ~/.zshrc)
echo 'export MY_VAR="value"' >> ~/.bashrc

# Linux - System-wide
echo 'MY_VAR="value"' >> /etc/environment
# Windows - Session
$env:MY_VAR = "value"

# Windows - Persistent (user)
[Environment]::SetEnvironmentVariable("MY_VAR", "value", "User")

# Windows - Persistent (system)
[Environment]::SetEnvironmentVariable("MY_VAR", "value", "Machine")

Process Management

Cross-Platform Commands

TaskLinux/macOSWindows
List processesps auxGet-Process
Find by namepgrep nginxGet-Process nginx
Kill by PIDkill 1234Stop-Process -Id 1234
Kill by namepkill nginxStop-Process -Name nginx
Force killkill -9 1234Stop-Process -Id 1234 -Force
Process treepstreeGet-CimInstance Win32_Process
Resource usagetop, htopTask Manager, Get-Process | Sort CPU

Signals (Linux/macOS)

Scripts and runbooks MUST use symbolic signal names, never numbers. Signal numbers are not portable: they differ between Linux and macOS, and on Linux they differ between CPU architectures.

SignalLinux (x86/ARM)macOSPurpose
SIGHUP11Reload configuration
SIGINT22Interrupt (Ctrl+C)
SIGKILL99Immediate termination (cannot be caught)
SIGTERM1515Graceful termination
SIGUSR11030User-defined
SIGUSR21231User-defined
SIGCHLD1720Child process stopped or exited
# Do: symbolic names work on every platform
kill -HUP $(pgrep nginx)     # Reload nginx
kill -TERM 1234              # Graceful stop
kill -USR1 1234              # User-defined signal 1
kill -KILL 1234              # Force kill (last resort)

# Don't: numeric signals are platform-specific
kill -10 1234                # SIGUSR1 on Linux, SIGBUS on macOS
kill -12 1234                # SIGUSR2 on Linux, SIGSYS on macOS

Why: on macOS, 10 and 12 are SIGBUS and SIGSYS, so kill -10 delivers a bus-error signal to a process expecting a reload request. Linux itself is not uniform either: SIGUSR1 is 10 on x86 and ARM, 30 on Alpha and SPARC, and 16 on MIPS and PA-RISC. Numbers MUST NOT be persisted in configuration files, container stop signals, or process supervisors that run on more than one platform; write SIGUSR1, not 10.


Choosing an OS

Decision Matrix

Use CaseRecommendedWhy
Web serversLinux (Debian)Stability, security, performance
ContainersLinuxNative container support
DatabasesLinuxPerformance, tooling
DevelopmentmacOS or LinuxPOSIX compatibility, tooling
.NET applicationsWindows or Linux.NET Core runs on both
Active DirectoryWindows ServerNative integration
File server (SMB)Windows or Linux (Samba)Depends on clients
GPU computeLinuxCUDA/driver support
Desktop appsMatch target usersNative experience

Debian vs Ubuntu

AspectDebianUbuntu
Release cycle~2 years6 months (LTS: 2 years)
Support length~5 years5 years (LTS)
StabilityMore conservativeNewer packages
Use caseServers, stabilityDesktop, cloud
DerivativesUbuntu, many othersMany derivatives

Recommendation: Use Debian for servers requiring maximum stability; Ubuntu LTS for cloud deployments with newer packages.


See Also