Structure of UNIX/Linux

 Operating system: The Kernel

UNIX is a layered operating system. The innermost layer is the hardware itself that provides the services for the OS. The operating system - the kernel -  interacts directly with the hardware and provides the services to the user programs. These user programs don't need to know anything about the hardware. They just need to know how to interact with the kernel and it's up to the kernel to provide the desired service. One of the big appeals of UNIX to programmers has been that most well written user programs are independent of the underlying hardware, making them readily portable to new systems.


User programs interact with the kernel through a set of standard system calls. These system calls request services to be provided by the kernel. Such services would include:

  • accessing a file: open close, read, write, link, or execute a file
  • starting or updating accounting records
  • changing ownership of a file or directory
  • changing to a new directory
  • creating, suspending, or killing a process
  • enabling access to hardware devices
  • setting limits on system resources.

UNIX is a multi-user, multi-tasking operating system. You can have many users logged into a system simultaneously, each running many programs. It's the kernel's job to keep each process and user separate and to regulate and guarantee access to resources like cpu, memory, disk and other I/O devices.

 The Shell

The shell sits between you and the operating system, acting as a command interpreter. It reads your terminal input and translates the commands into actions taken by the system. The shell is analogous to in DOS.

The original shell was the Bourne shell, sh. Every UNIX platform will either have the Bourne shell or a Bourne compatible shell available. On most Linux systems the default shell is bash (Bourne Again SHell). There are other type of shells like csh (C SHell), ksh (Korn SHell), zsh (Z Shell) or tcsh (TENEX-C Shell).

The shell - regardless which implementation is being used - has very good features for controlling input and output, it has job control, so that you can send running jobs to background and later call them back to the foreground. It also provides a very useful history feature which allows you to modify and repeat previously executed commands with its built-in in-line command editor.

At login the system checks whether a user can be authenticated and its access is not restricted. If all this is successful then a shell is executed as specified in /etc/shadow file.

nobody:x:99:99:Unprivileged Nobody:/dev/null:/bin/false bb:x:1001:244:Big Brother:/usr/local/bb:/bin/bash

The last field will tell the default shell of a user. /bin/false or /bin/nologin means the user cannot log directly into the system. This is a security feature to prevent access to a system.

When you log into the system you are given a default shell. When the shell starts up it reads its start up files and may set environment variables, command search paths, and command aliases, and executes any commands specified in these files. The shell will display a prompt sign to signal it is ready to accept commands from user. The default prompt for the Bourne shell is $(or #, for the root user).

Which files are run on start up depend on whether it is:

  • an interactive login shell (when you log in using Putty or SecureCRT)
    • The shell first executes the commands in /etc/profile. By default when called from bash, a command in this file calls /etc/bashrc. Root user can set up this file to establish system wide default characteristics for all bash users.
    • Next the shell looks for ~/.bash_profile, ~/.bash_login, and ~/.profile (~/ is an abbreviation for your home directory), in that order, executing the commands in the first of these files it finds. You can put commands in one of these files to override the defaults set in /etc/profile.
    • When you log out, bash executes commands in the ~/.bash_logout file. Usually commands that clean up after a session, such as those that remove temporary files, go in this file.
    • a non-interactive login shell (when you issue bash command)
      • The commands in the preceding start-up files are not executed by interactive, non-login shells. However, these shells inherit from the login shell variables that are set by these start-up files and call scripts in the user HOME directory.
      • a non-login non-interactive shell (used to execute a shell script)
        • The commands in the previously described start-up files are not executed by non-interactive shells, such as those that run shell scripts. However, these shells inherit from the login shell variables that are set by these start-up files.

Start-up scripts can be personalized but keep in mind that those in /etc are general for all users. Modifying a variable in ~/.bash_profile allows changes you make in an interactive session to propagate to sub-shells. Modifying a variable in ~/.bashrc overrides changes inherited from a parent shell.

Environmental variables are used to provide information to the programs you use. You can have both globalenvironment and localshell variables. Global environment variables are set by your login shell and new programs and shells inherit those settings. Local shell variables are used only by that actual shell and are not passed on to other processes. A child process cannot pass a variable back to its parent process.

The current environment variables are displayed with the "env" command. Some common ones are:

  • DISPLAY The graphical display to use, e.g. nyssa:0.0
  • EDITOR The path to your default editor, e.g. /usr/bin/vim
  • GROUP Your login group, e.g. staff, bb
  • HOME Path to your home directory, e.g. /home/rfejes
  • IFS Internal field separators, usually any white space (defaults to tab, space and <newline>)
  • LOGNAME The name you login with, e.g. frank
  • PATH Paths to be searched for commands, e.g. /usr/bin:/usr/ucb:/usr/local/bin
  • PS1 The primary prompt string, Bourne shell only (defaults to $)
  • PS2 The secondary prompt string, Bourne shell only (defaults to >)
  • SHELL The login shell you're using, e.g. /usr/bin/sh
  • TERM Your terminal type, e.g. xterm
  • USER Your username, e.g. rfejes

Many environment variables will be set automatically when you login. You can modify them or define others with entries in your start up files or at anytime within the shell. The PATH variable specifies the directories to be automatically searched for the command you specify.

With the Bourne Again shell, bash, and many newer shells, you can put jobs into the background at anytime by appending "&" to the command, as with sh.

You can also push programs to background by typing ^Z (Control-Z). This only will suspend the job so you need to issue "bg" command to put it into the background. To bring it back to the foreground type "fg".

You can have many jobs running in the background. When they are in the background they are no longer connected to the keyboard for input, but they may still display output to the terminal, interspersing with whatever else is typed or displayed by your current job. Be aware that jobs running in the background of your shell are prone to be terminated if you close their parent shell i.e. you log out or forcibly close the session. Your keyboard is connected only to the current, foreground job.

The built-in jobs command allows you to list your background jobs. You can use the kill command to kill a background job. With the %n notation you can reference the nth background job with either of these commands, replacing n with the job number from the output of jobs. So you would kill the second background job with "kill %2" and bring the third job to the foreground with "fg %3".

Shells have some built-in commands - just like in DOS/Windows such as cd, echo, pwd, exit, for, while, test, wait, umask, jobs - others do need to be searched. Shell will look for any external program in directories specified by the PATH variable. Here is an example of the variable from bbops2001: