UNIX is not easily defined, because it is an “ideal” operating system that has been instantiated by different vendors over the years, in some quite nonstandard ways. However, there are a number of features of UNIX and UNIX-like systems (such as Linux) that can be readily described. UNIX systems have a core kernel that is responsible for managing core system operations, such as logical devices for input/output (such as /dev/pty, for pseudoterminals), and allocating resources to carry out user-specified and system-requisite tasks. In addition, UNIX systems have a hierarchical file system that allows both relative and absolute file path naming, and is extremely flexible. UNIX file systems can be mounted locally, or remotely from a central file server. All operations on a UNIX system are carried out by processes, which may spawn child processes or other lightweight processes to perform discrete tasks.
Processes can be uniquely identified by their process ID (PID).
Originally designed as a text processing system, UNIX systems share many tools that manipulate and filter text in various ways. In addition, small, discrete utilities can be easily combined to form complete applications in rather sophisticated ways. These applications are executed from a user shell, which defines the user interface to the kernel.
Although GUI environments can be constructed around the shell, they are not mandatory.
UNIX is multiprocess, multiuser, and multithreaded. This means that more than one user can execute a shell and applications concurrently, and that each user can execute applications concurrently from within a single shell. Each of these applications can then create and remove lightweight processes as required.
Because UNIX was created by active developers, rather than operating system gurus, there was always a strong focus on creating an operating system that suited programmer’s needs. A Bell System Technical Journal article in 1978 lists the key guiding principles of UNIX development:
Create small, self-contained programs that perform a single task. When a new task needs to be solved, either create a new program that performs it or combine tools from the toolset that already exists to arrive at a solution. This is a similar orientation to the current trend towards encapsulation and independent component building (such as Enterprise JavaBeans), where complicated systems are built from smaller interacting but logically independent modules.
Programs should accept data from standard input and write to standard input; thus, programs can be “chained” to process each other’s output sequentially. Avoid interactive input in favor of command-line options that specify a program’s actions to be performed. Presentation should be separated from what a program is trying to achieve. These ideas are consistent with the concept of piping, which is still fundamental to the operation of user shells. For example, the output of the ls command to list all files in a directory can be "piped" using the | symbol to a program such as grep to perform pattern matching. The number of pipes on a single command-line instruction is not limited.
Creating a new operating system or program should be undertaken on a scale of weeks, not years: the creative spirit that leads to cohesive design and implementation should be exploited. If software doesn’t work, don’t be afraid to build something better. This process of iterative revisions of programs has resurfaced in recent years with the rise of object-oriented development.
Make best use of all the tools available, rather than asking for more help. The motivation behind UNIX is to construct an operating system that supports the kinds of toolsets required for successful development.
This is not intended to be an exhaustive list of the characteristics that define UNIX, but these features are central to understanding the importance that UNIX developers often ascribe to the operating system. It is designed to be a programmer-friendly system.