|< Day Day Up >|
A process is the execution of a command by Linux. The shell that starts when you log in is a command , or a process, like any other. When you give the name of a Linux utility on the command line, you initiate a process. When you run a shell script, another shell process is started and additional processes are created for each command in the script. Depending on how you invoke the shell script, the script is run either by the current shell or, more typically, by a subshell (child) of the current shell. A process is not started when you run a shell builtin, such as cd.
fork system call
Like the file structure, the process structure is hierarchical, with parents, children, and even a root. A parent process forks a child process, which in turn can fork other processes. (The term fork indicates that, as with a fork in the road, one process turns into two. Initially the two forks are identical except that one is identified as the parent and one as the child. You can also use the term spawn; the words are interchangeable.) The operating system routine, or system call, that creates a new process is named fork.
When Linux begins execution when a system is started, it starts init, a single process called a spontaneous process, with PID number 1. This process holds the same position in the process structure as the root directory does in the file structure: It is the ancestor of all processes that the system and users work with. When the system is in multiuser mode, init runs getty or mingetty processes, which display login: prompts on terminals and virtual consoles. When someone responds to the prompt and presses RETURN, getty hands control over to a utility named login, which checks the username and password combination. After the user logs in, the login process becomes the user's shell process.
Linux assigns a unique PID (process identification) number at the inception of each process. As long as a process exists, it keeps the same PID number. During one session the same process is always executing the login shell. When you fork a new process for example, when you use an editor the PID number of the new (child) process is different from that of its parent process. When you return to the login shell, it is still being executed by the same process and has the same PID number as when you logged in.
The following example shows that the process running the shell forked (is the parent of) the process running ps (page 127). When you call it with the f option, ps displays a full listing of information about each process. The line of the ps display with bash in the CMD column refers to the process running the shell. The column headed by PID identifies the PID number. The column headed PPID identifies the PID number of the parent of the process. From the PID and PPID columns you can see that the process running the shell (PID 21341) is the parent of the process running sleep (PID 22789). The parent PID number of sleep is the same as the PID number of the shell (21341).
$ sleep 10 &  22789 $ ps -f UID PID PPID C STIME TTY TIME CMD alex 21341 21340 0 10:42 pts/16 00:00:00 bash alex 22789 21341 0 17:30 pts/16 00:00:00 sleep 10 alex 22790 21341 0 17:30 pts/16 00:00:00 ps -f
Refer to page 746 for more information on ps and the columns it displays with the f option. A second pair of sleep and ps f commands shows that the shell is still being run by the same process but that it forked another process to run sleep:
$ sleep 10 &  22791 $ ps -f UID PID PPID C STIME TTY TIME CMD alex 21341 21340 0 10:42 pts/16 00:00:00 bash alex 22791 21341 0 17:31 pts/16 00:00:00 sleep 10 alex 22792 21341 0 17:31 pts/16 00:00:00 ps -f
You can also use pstree (or ps forest, with or without the e option) to see the parent child relationship of processes. The next example shows the p option to pstree, which causes it to display PID numbers:
$ pstree -p init(1)-+-acpid(1395) |-atd(1758) |-crond(1702) ... |-kdeinit(2223)-+-firefox(8914)---run-mozilla.sh(8920)---firefox-bin(8925) | |-gaim(2306) | |-gqview(14062) | |-kdeinit(2228) | |-kdeinit(2294) | |-kdeinit(2314)-+-bash(2329)---ssh(2561) | | |-bash(2339) | | '-bash(15821)---bash(16778) | |-kdeinit(16448) | |-kdeinit(20888) | |-oclock(2317) | '-pam-panel-icon(2305)---pam_timestamp_c(2307) ... |-login(1823)---bash(20986)-+-pstree(21028) | '-sleep(21026) ...
The preceding output is abbreviated. The line that starts with kdeinit shows a graphical user running many processes, including firefox, gaim, and oclock. The line that starts with login shows a textual user running sleep in the background while running pstree in the foreground. Refer to "$$: PID Number: PID Number" on page 478 for a description of how to instruct the shell to report on PID numbers.
Executing A Command
fork and sleep
When you give the shell a command, it usually forks (spawns) a child process to execute the command. While the child process is executing the command, the parent process sleeps. While a process is sleeping, it does not use any computer time but remains inactive, waiting to wake up. When the child process finishes executing the command, it tells its parent of its success or failure via its exit status and then dies. The parent process (which is running the shell) wakes up and prompts for another command.
When you run a process in the background by ending a command with an ampersand (&), the shell forks a child process without going to sleep and without waiting for the child process to run to completion. The parent process, which is executing the shell, reports the job number and PID number of the child and prompts for another command. The child process runs in the background, independent of its parent.
Although the shell forks a process to run most of the commands you give it, some commands are built into the shell. The shell does not need to fork a process to run builtins. For more information refer to "Builtins" on page 132.
Within a given process, such as your login shell or a subshell, you can declare, initialize, read, and change variables. By default, however, a variable is local to a process. When a process forks a child process, the parent does not pass the value of a variable to the child. You can make the value of a variable available to child processes (global) by using the export builtin under bash (page 475) or the setenv builtin under tcsh (page 356).
|< Day Day Up >|