Linux online course

Understanding /etc/inittab and SysV Init Runlevels in Linux

Learn how traditional SysV init uses /etc/inittab to select runlevels, start boot scripts, supervise processes, and differ from systemd.

/etc/inittab is the main configuration file used by traditional System V init, commonly called SysV init. It tells the system's initialization process what to do during boot, when changing runlevels, and when supervising long-running processes.

This topic is most relevant to older Linux installations and legacy systems. Many current distributions use systemd instead, so the file may be absent, ignored, or retained only for compatibility.

What Are init and SysV init?

init is the userspace initialization and process-management program. Historically, it runs as PID 1, the first process started after the kernel has initialized enough hardware and mounted an initial root filesystem.

SysV init organizes system operation around runlevels. A runlevel is a defined operating state that determines which services and tasks should be active. The traditional init program reads /etc/inittab and uses its entries to decide how to reach and maintain that state.

The Role of /etc/inittab During Boot

At a high level, a SysV-style boot proceeds as follows:

  1. The kernel starts the first userspace process, usually init as PID 1.
  2. Init reads its configuration, including /etc/inittab when that file is used by the implementation.
  3. Init performs early initialization tasks such as those described by sysinit entries.
  4. Init determines the target runlevel, commonly from an initdefault entry unless a boot option or administrator action supplies another one.
  5. Init runs the entries and scripts associated with that runlevel.
  6. Services such as terminal login programs are started, making the system available for use.

A later runlevel change causes init to process entries applicable to the new operating state. Depending on the implementation and scripts, services associated with the old state may be stopped and services for the new state started.

The /etc/inittab Entry Format

Most entries have four colon-separated fields in this order:

id:runlevels:action:process
FieldPurposeTypical contentsImportant behavior
idIdentifies the entryOne to four charactersUsed by init to distinguish entries
runlevelsStates in which the entry appliesOne or more digits, such as 2345Some actions leave this field empty
actionControls when and how init invokes the processwait, respawn, initdefaultDetermines waiting and supervision behavior
processCommand or script to executeAn absolute path plus argumentsMay be empty for actions that do not launch a process

Lines beginning with # are comments. Blank lines are ignored. Colons are field separators, so removing or adding one can shift all later fields and change the meaning of an entry. Commands containing special shell characters should be written according to the local init implementation's parsing rules.

Understanding the id Field

The id field labels an entry for init's internal use. Traditional implementations commonly limit it to one through four characters. IDs should be distinct where the implementation requires uniqueness and should be meaningful enough to identify the entry's purpose.

An entry ID is not:

  • a Linux user name;
  • a process ID or PID;
  • a runlevel number.

For example, l3 can identify the entry that handles runlevel 3, while co might identify a console login entry.

Understanding the runlevels Field

This field lists the numeric runlevels in which an entry applies. Multiple runlevels can be listed together without separators:

co:2345:respawn:/sbin/agetty tty1 linux

This illustrative entry applies in runlevels 2, 3, 4, and 5. An entry can also name one runlevel, such as 3. Some actions, including initdefault and commonly sysinit, do not use this field and leave it empty.

Runlevel entries often invoke a central runlevel-management script. The runlevel number tells that script which services to start or stop.

Common action Values

ActionWhen init runs itWhether init waitsTypical use
initdefaultDuring normal startup to choose the default runlevelNot applicableSelecting the normal boot operating state
sysinitDuring early, one-time initializationImplementation-dependent, normally completed before ordinary runlevel processingBasic system setup before the target runlevel
bootDuring bootNoA boot-time command that need not block later processing
bootwaitDuring bootYesA boot-time command that must finish before continuation
waitWhen entering a matching runlevelYesRunlevel scripts that must complete before init proceeds
respawnAt the applicable operating state and after terminationInit supervises it rather than treating it as a one-time taskPersistent processes such as terminal login programs

Action names and details can vary slightly between SysV init implementations. Always check the documentation installed on the target system before relying on an uncommon action.

initdefault

An initdefault entry selects the normal startup runlevel. It uses the runlevels field and does not launch a process, so the process field is empty:

id:3:initdefault:

This example conceptually selects runlevel 3. The appropriate value depends on the distribution. Never select runlevel 0 or 6 as the default: 0 normally halts or powers off the system, while 6 normally reboots it.

sysinit, boot, and bootwait

sysinit is intended for early system initialization. A boot entry starts a boot-time process without waiting for it to finish. A bootwait entry also runs during boot but makes init wait for completion. The distinction matters when later initialization depends on the command finishing.

wait

A wait entry runs when its listed runlevel is entered and makes init wait for the command to return. This is common for an rc script that starts and stops groups of services:

l3:3:wait:/etc/init.d/rc 3

Here, l3 is the ID, 3 is the applicable runlevel, wait is the action, and /etc/init.d/rc 3 is the process command. The script receives 3 as an argument and performs the distribution-specific work for entering runlevel 3.

respawn

respawn tells init to start a process and start it again if it exits. This is useful for a persistent terminal login service:

co:2345:respawn:/sbin/agetty tty1 linux

The exact getty path, terminal name, and arguments vary. If the program exits immediately, init may repeatedly restart it. Implementations commonly apply rate limiting or temporarily disable repeated restarts to prevent a respawn loop from consuming resources. Test custom respawn commands and inspect logs before enabling them on a production console.

Traditional Runlevels

RunlevelCommon conventionCautions and distribution differences
0Halt or power offDestructive transition state; do not use as a normal default
1Single-user, maintenance, or rescue modeOften provides limited services and administrative access
2Multi-user modeExact service set varies, especially between distributions
3Multi-user mode, commonly without a graphical loginConvention is not universal
4Often unusedMay be locally customized or assigned a special purpose
5Multi-user mode, often with graphical servicesGraphical-mode meaning is distribution-specific
6RebootDestructive transition state; do not use as a normal default

Runlevels 2 through 5 are conventions rather than a universal standard. The actual services active in each state are determined by the distribution's rc directories, scripts, and local configuration.

Runlevel Script Entries

A common configuration has several entries that call one rc script with different runlevel arguments:

l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6

Each ID combines a lowercase letter with a runlevel number in this illustrative pattern. The same script is reused, but the argument tells it which operating state to enter. The wait action is important because init waits while the script starts or stops services before continuing with later processing.

Runlevel 4 is omitted here to show that it may be unused. Omitting it does not remove the runlevel from init itself; it simply means this particular configuration has no corresponding entry in the example.

Checking the Default and Current Runlevel

On a traditional SysV system, inspect the initdefault line to identify the configured normal startup state:

grep -vE '^[[:space:]]*($|#)' /etc/inittab

The legacy commands below may report the current and previous runlevel:

runlevel
who -r

Availability and output depend on the distribution and init implementation. A boot parameter or an administrator-requested transition can override the normal default, so the configured default and the currently active runlevel are not always identical.

Editing and Applying Changes Safely

  1. Confirm that the machine actually uses SysV init before assuming /etc/inittab controls boot behavior.
  2. Make a backup before editing a boot-critical file.
  3. Preserve the four-field structure and check every path, argument, permission, and runlevel.
  4. Ensure scripts used with wait or bootwait can return; a script that hangs can stall boot or a runlevel transition.
  5. Keep console, serial, out-of-band, or recovery access available before changing login or default-runlevel entries.
  6. On a supported SysV system, ask init to reread its configuration rather than rebooting unnecessarily.
telinit q
init q

Use only the command supported by the installed init implementation and local documentation. A reload does not necessarily rerun every boot or runlevel action. A controlled runlevel transition or reboot may be needed to observe a particular change, but test destructive states carefully.

Troubleshooting Common Problems

Editing the file has no effect

First identify PID 1 and the active init implementation:

ps -p 1 -o pid,comm,args
readlink -f /sbin/init

The host may use systemd or another init system, or the file may exist only for compatibility. On a SysV host, init may simply need a supported configuration reload.

The system enters an unexpected mode

Review the initdefault entry, check the current runlevel with runlevel or who -r, and verify the distribution's conventions. A boot option or administrator action may have selected a different state.

A service or login prompt continuously restarts

A respawn-managed command may exit immediately because its path, arguments, terminal, permissions, or configuration are wrong. Run the command manually in a safe environment, inspect logs, correct the underlying failure, and disable the failing respawn entry if necessary.

Boot stalls while entering a runlevel

A wait entry may invoke a script that hangs while waiting for storage, networking, a device, or another dependency. Use console or rescue access, inspect init and service logs, and isolate the blocking script.

No console login appears

Check whether the getty or equivalent respawn entry was removed, malformed, restricted to different runlevels, or given an invalid terminal device or command path. Compare it with a known-good configuration using alternate console or recovery access.

The system immediately halts or reboots

This commonly indicates that runlevel 0 or 6 was selected as the default, or that an rc script received the wrong argument. Correct the configuration from a rescue environment and validate it before rebooting.

Modern Linux Compatibility

Most current Linux distributions use systemd rather than traditional SysV init. Systemd uses units and targets; a target groups units to represent an operating state similar in concept to a runlevel.

Legacy SysV conceptModern systemd counterpartNotes
Default runlevelDefault targetInspect with systemctl get-default
Runlevel service groupTarget and its dependenciesThe relationship is conceptual, not an exact one-to-one mapping
init process as PID 1systemd as PID 1Both provide initialization and process-management responsibilities, but their models differ
/etc/inittabUnit and target configurationSystemd normally does not use inittab as its controlling configuration
/etc/init.d service scriptsNative units or generated compatibility unitsLegacy scripts may remain even when systemd controls boot
systemctl get-default
systemctl list-units --type=target

For example, a legacy multi-user runlevel may correspond approximately to multi-user.target, while a graphical runlevel may correspond approximately to graphical.target. The mapping depends on the distribution and enabled services; it is not a guarantee that every runlevel entry has a direct systemd equivalent.

Upstart and other initialization systems use different configuration models as well. The presence of traditional scripts under /etc/init.d does not prove that /etc/inittab controls the machine.

Key Exam Notes

  • /etc/inittab is associated with traditional SysV init, not automatically with every Linux system.
  • The four fields are id:runlevels:action:process.
  • initdefault selects a default runlevel and does not launch a process.
  • sysinit handles early initialization; boot does not wait, while bootwait does.
  • wait runs a matching command and waits for it to finish.
  • respawn restarts a process after it exits and is commonly used for getty-style login programs.
  • Runlevel 0 halts, runlevel 6 reboots, and runlevel 1 commonly provides single-user maintenance mode.
  • Runlevels 2 through 5 have distribution-specific meanings.
  • Systemd targets are the modern conceptual counterpart to runlevels.

For related Linux command and filesystem fundamentals, see Linux, Show The Full Path Of Shell Commands, and Determine File Type.