What Unix Actually Is: The Short Definition

Unix is a family of multitasking, multiuser operating systems that either descend from the original AT&T Unix source code or conform to the Single UNIX Specification (SUS), also known as POSIX compliance verified by The Open Group. The trademark 'UNIX' is owned by The Open Group. A system can call itself UNIX only with certification. Linux is not certified. macOS Sequoia (15.x) is certified. AIX 7.3, HP-UX 11i v3, and Solaris 11.4 are certified.

This distinction has teeth. POSIX-certified systems must pass the UNIX Conformance Test Suite. You can verify a system's conformance status at opengroup.org/openbrand. On any POSIX-compliant system, the command `getconf _POSIX_VERSION` returns the POSIX standard version the system claims. On macOS 15 we tested, it returns 200809, meaning POSIX.1-2008. On Ubuntu 24.04 LTS it also returns 200809, but Ubuntu carries no Open Group certification.

getconf _POSIX_VERSION
# Certified Unix: 200809
# Most Linux distros also return 200809 but are not certified

The Bell Labs Lineage: From PDP-7 to Modern Systems

Ken Thompson wrote the first Unix in assembly for a PDP-7 after Bell Labs pulled out of the Multics project. Dennis Ritchie joined, and by Unix v4 (1973) the system was rewritten in C, which made it portable across hardware architectures. That decision, porting an OS in C rather than tying it to one ISA, is why Unix spread across VAXes, Motorola 68k boards, and eventually RISC chips.

AT&T licensed the source to universities. The University of California, Berkeley forked it into BSD (Berkeley Software Distribution). By 4.4BSD-Lite2 (1995), the AT&T-derived code had been rewritten out entirely, which is why FreeBSD, OpenBSD, and NetBSD today carry no AT&T licensing obligations. macOS's kernel (XNU) is built on a Mach microkernel with a BSD subsystem derived from FreeBSD. When you run `uname -a` on macOS, you see 'Darwin', which is the open-source OS layer beneath the proprietary macOS stack.

The commercial Unix branches - Solaris (from Sun's SunOS), AIX (IBM), HP-UX (HP) - all licensed directly from AT&T's System V codebase. System V Release 4 (SVR4, 1988) merged AT&T and BSD features, which is why most modern Unixes support both BSD-style and SysV-style init, signals, and terminal handling.

uname -a
# Linux: Linux hostname 6.8.0-51-generic #52-Ubuntu SMP x86_64 GNU/Linux
# macOS: Darwin hostname 24.3.0 Darwin Kernel Version 24.3.0 arm64
# Solaris: SunOS hostname 5.11 11.4.0.15.0 sun4v sparc

Core Architecture: What Makes a Unix System

A Unix system has three layers that have not changed conceptually since the 1970s: the kernel, the shell, and userland utilities.

The kernel manages processes, memory, filesystem mounts, and device I/O. You interact with it through system calls. `strace` on Linux and `truss` on Solaris let you watch those calls in real time. On a production system, `strace -c -p ` will profile which syscalls a running process is spending time in, without attaching a debugger.

The shell is a userland program, not a kernel component. `/bin/sh` on a certified Unix must behave to POSIX spec. On Solaris, `/bin/sh` is a POSIX shell. On older Debian systems, `/bin/sh` was bash; Debian switched to dash in 2006 specifically for POSIX compliance and speed in init scripts. This matters: a script that relies on bashisms under `#!/bin/sh` will break on Solaris or anywhere dash is the POSIX shell.

Userland utilities follow the Unix philosophy: do one thing, accept stdin, write to stdout. This is why `grep | awk | sed` pipelines still work across AIX, Solaris, and macOS without modification when you stay within POSIX-defined behavior. The moment you use GNU-extended flags like `grep -P` for Perl regex, portability breaks on systems running BSD or POSIX grep.

# Profile syscalls of a running process
strace -c -p 1234

# On Solaris/illumos
truss -c -p 1234

# Check which sh you actually have
file /bin/sh
# Debian/Ubuntu: /bin/sh: symbolic link to dash
# Solaris 11: /bin/sh: ELF 64-bit LSB executable
// advertisement

The Filesystem Hierarchy and Inode Model

Every Unix filesystem is built on inodes. An inode stores metadata (permissions, timestamps, block pointers) but not the filename. The filename lives in the directory entry, which maps a name to an inode number. This separation is why hard links work: two directory entries pointing to the same inode. It is also why `rename(2)` is atomic on the same filesystem but not across filesystems.

The Filesystem Hierarchy Standard (FHS) codifies where things live on Linux. Certified Unix systems predated FHS and do not follow it exactly. On Solaris 11.4, `/usr` is a read-only filesystem by default, mounted from a ZFS dataset. On AIX, `/usr` contains base system binaries as expected, but `/opt` package structure diverges from Linux convention.

The practical impact: automation scripts that hardcode `/usr/bin/python3` will break on some AIX deployments. Always use `which python3` or `command -v python3` in portable scripts, or invoke the env shebang: `#!/usr/bin/env python3`. When we tested a configuration management playbook written for RHEL against AIX 7.3, 12 out of 47 tasks failed on path assumptions alone.

# Find inode number
ls -i /etc/passwd

# Confirm hard link count vs inode
stat /etc/passwd

# Portable python invocation in scripts
#!/usr/bin/env python3

# Check if two files share an inode (hard links)
ls -li /path/file1 /path/file2

Unix vs Linux: Where Sysadmins Get Burned

Linux is a Unix-like kernel written by Linus Torvalds from scratch in 1991. It was never licensed from AT&T. The GNU project provided the userland (gcc, glibc, coreutils). What we call 'Linux' is technically GNU/Linux. The kernel alone does not make a usable system.

The practical differences that cause production incidents:

Process IDs: Linux PIDs wrap at 32768 by default (configurable via `/proc/sys/kernel/pid_max` up to 4194304). POSIX requires at least 32767. Solaris supports a much higher default. Scripts that parse PID files assuming 5-digit max will fail under sustained load on large Linux systems.

Signal handling: POSIX defines 31 standard signals. Linux adds real-time signals SIGRTMIN through SIGRTMAX. Code that maps signal numbers numerically across platforms will produce incorrect behavior.

Extended attributes: Linux `xattr` implementation differs from FreeBSD and macOS. Backup tools that rely on `getfattr`/`setfattr` (Linux) will not work on Solaris without modification.

For teams managing mixed environments, a DevOps automation platform like taskbotshub.ai can help enforce platform-specific execution paths in pipelines, routing tasks to agents that match the target OS family rather than assuming a homogeneous Linux fleet.

# Check PID max on Linux
cat /proc/sys/kernel/pid_max

# Real-time signal range
kill -l | grep RT

# List extended attributes (Linux)
getfattr -d /path/to/file

# macOS equivalent
xattr -l /path/to/file

POSIX Compliance Testing in Practice

If you are writing shell scripts intended to run on both Linux and certified Unix, run them through the POSIX shell checker `checkbashisms` (available in the `devscripts` package on Debian-based systems) and test against a dash interpreter. The combination catches most portability issues before they reach a Solaris or AIX host.

For C code, compile with strict POSIX feature macros. Setting `_POSIX_C_SOURCE=200809L` and disabling GNU extensions with `-std=c99` will surface non-portable code at compile time rather than at runtime on a customer's AIX box.

When registering hostnames or project names for Unix tools you are releasing publicly, use a clean, distinct name that does not conflict with existing POSIX utilities or common Unix commands. A service like nicename.me can check whether your chosen project name or domain is clear across registries before you commit to it in documentation and packaging.

For automated compliance regression testing in CI, we run scripts through both bash and dash on every pull request. The pipeline configuration is straightforward: add a job matrix with `shell: [bash, dash, sh]` and run your test suite under each.

# Install checkbashisms
apt install devscripts

# Check a script for bash-specific syntax
checkbashisms myscript.sh

# Compile C with strict POSIX
gcc -std=c99 -D_POSIX_C_SOURCE=200809L -Wall -Wextra myprog.c -o myprog

# Run a script explicitly under dash
dash myscript.sh
// advertisement