How these process concepts are related together - background, zombie, daemon and without controlling terminal?

I feel that they are somehow close, especially through the concept of controlling terminal, but there is still not much info for me to tell a story, like if you need to explain something to a child reading an article about Linux without lying too much.

UPDATE #1: For example (I don't know if that's true)

  • background -- zombie - foreground process can not become zombie, because zombie is a background process that was left without a parent
  • daemon -- without ctty - all daemons run without ctty, but not all processes withoutctty are daemons
  • background -- daemon - a background process can be retrieved to run interactively again, daemon is not
  • zombie -- without ctty - zombie is indifferent if there is ctty attached to it or not
  • background -- without ctty - processes sent to background while they have ctty, and become daemons or die if the ctty is taken from them
  • A foreground process can certainly be a zombie, although usually not for any appreciable period of time -- the usual way for a shell (or other program) to run a subprocess in the foreground is to fork() off a copy of yourself, use exec() in that copy to replace it with what you want to run, and use wait() in the original instance of program (not the copy that ran exec()). In the very, very short period of time between when the child exits and when the wait() reaps that exit status (removing it from the process table and returning it to the caller), you have a zombie. Mar 21 '17 at 19:30
  • @CharlesDuffy is it possible to send parent to background while leaving child running in foreground? Apr 9 '17 at 6:17
  • In typical job control, the shell doesn't even know that the grandchild is separate from its direct child at all; it's just waiting for its child to exit, and if the child is waiting for a grandchild to exit, well, that's the child's business. Which is to say -- from the perspective of the shell that spawned the parent, it's only dealing with one unit. Apr 9 '17 at 16:51

In brief, plus links.


a process that has exited/terminated, but whose parent has not yet acknowledged the termination (using the wait() system calls). Dead processes are kept in the process table so that their parent can be informed that their child of the child process exiting, and of their exit status. Usually a program forking children will also read their exit status as they exit, so you'll see zombies only if the parent is stopped or buggy.


controlling terminal, session, foreground, background

These are related to job control in the context of a shell running on a terminal. A user logs in, a session is started, tied to a terminal (the controlling terminal) and a shell is started. The shell then runs processes and sends them on the foreground and background as the user wishes (using & when starting the process, stopping it with ^Z, using fg and bg). Processes in the background are stopped if reading or writing from the terminal; processes in the foreground receive the interrupt signal if ^C is hit on the terminal. (It's the kernel's terminal driver that handles those signals, the shell controls which process (group) is sent to the foreground or background.



A process running as a daemon is usually something that shouldn't be tied to any particular terminal (or a login session, or a shell). It shouldn't have a controlling terminal, so that it won't receive signals if the terminal closes, and one usually doesn't want it to do I/O on a terminal either. Starting a daemon from the command line requires breaking all ties to the terminal, i.e. starting a new session (in the job control sense, above) to get rid of the controlling terminal, and closing the file handles to the terminal. Of course something started from init, systemd or similar outside a login session wouldn't have these ties to begin with.

Since a daemon doesn't have a controlling terminal, it's not subject to job control, and being in the "foreground" or "background" in the job control sense doesn't apply. Also, daemons usually re-parent to init which cleans them as they exit, so you don't usually see them as zombies.



Zombie isn't really related to the others; it simply is a process that has terminated, but its parent process has not yet read its exit status with waitpid() or similar. You shouldn't see these unless a process is buggy or stopped.

A daemon is a program that runs without a controlling terminal. Typically when you run the program, it fork()s itself, and the parent exits so the shell thinks the command has finished, and the child process detaches from the terminal and escapes the login session. Since its parent process exited, its parent process ID becomes 1, which is traditionally the init program, or these days, systemd. This process makes sure to reap its children when they die so you don't end up overrun with zombies.

A process can be associated with a controlling terminal, which is where it normally gets its input from and sends its output to. The terminal also can send signals to processes attached to it, and identifies a process group as the foreground group. Processes that are in the foreground group are allowed to read input from the terminal, and are sent SIGINT and SIGSUSP signals when you press Ctrl-C and Ctrl-Z. Any process not in the foreground group that tries to read from the terminal is suspended with SIGTSTP.

The shell creates different process groups for each of the pipeline commands you ask it to run, and shifts which one is the foreground group to move jobs between the foreground and background. When you run a command, normally the shell makes a new process group and makes that group the foreground group. If you suffix it with an & then the shell simply leaves the foreground group where it was and so the new group is in the background. Pressing Ctrl-Z sends SIGSUSP to the foreground group, which causes most commands to suspend, but instead of suspending, the shell changes the active foreground group back to itself so it can prompt you for a new command.

The bg command sends SIGCONT to a process group so that it can resume running in the background after having been suspended with SIGSUSP. fg changes the foreground group to one of the existing groups already running in the background, bringing it to the foreground.


Ok, here is my explanation with a stress on differences between these types of processes (short yet informative):

  • zombie - process that has just exited (finished it's execution) but still has an entry in a process table. Note: zombie process still has a parent and usually the whole point of it's existence is to let that parent process know about the result of child's execution (exit code etc.).
  • disowned process (without controlling terminal) - process that was either explicitly disown'ed by user or designed to be detached from a parent process tree. It would still run even if the parent process would finish execution. For example, user ssh'ed to a remote machine, started something like a web server, then run disown on it and exited from ssh session. The process would still be running as it's not a part of a parent process tree anymore. Process also can be disowned running it with nohup.
  • background process - runs in a background - doesn't split output to a user's tty. Either was run with & in the end, or forked itself to a background by design. Other option to send a process to a background is to start it and press ctrl+z. Yet, when the parent process will terminate, the child running in a background would also terminate (note by @psusi - the prior fact is only true with processes started from a terminal by user; otherwise child process becomes an 'orphant' and gets an init process (pid 1) as a parent).
    • daemon - very similar to the background process. Also runs in a background but most probably was forked implicitly (by design). Usually it sits quietly in a background waiting for some even occur and only then does an actual work (incoming connection etc). Actually, daemon can be both disowned (more probably) and background process depending on it's design.

Hope this explanation would help to distinguish these types of processes.

  • Nice. Process table belongs to parent? So zombies die without their master? Mar 21 '17 at 9:41
  • Table is not a right word. It's rather a process tree. Yes, sure, parent is not bounded to terminate after it's child terminated (but it can do so if it was waiting for a child to finish processing of some sort of stuff). But if parent would terminate - child would terminate definitely. You can run top from your terminal and then press shift-v to see process trees in a wild.
    – ddnomad
    Mar 21 '17 at 9:46
  • 1
    A parent terminating does not kill its children. The orphaned children have their parent process ID changed to init ( 1 ).
    – psusi
    Mar 21 '17 at 14:36
  • @psusi you're right, I forgot that it's so only with processes started in terminal. I'll correct my answer.
    – ddnomad
    Mar 21 '17 at 14:44
  • I would just remove the "it would disappear from a table soon" sentence. It suggest that it somehow automatically fades away after some time, but that is not the case; the "disappearing" is a very concrete event.
    – AnoE
    Mar 21 '17 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.