Javascript required
Skip to content Skip to sidebar Skip to footer

After Killing Foreground Proccess Continue Background Process C

A process is simply the instance of a running program. Processes are a fundamental concept of Linux systems and we'll start with discussing what can be termed as the life cycle of processes. This includes the concepts of parent and child processes and while going through this subject, we'll also introduce some essential commands that allow us to view ongoing processes of our terminal. These commands are ps, jobs and top.

Next we discuss foreground and background processes and how processes can be managed practically using UNIX commands and operators. These commands include sleep, fg, bg, jobs and kill. The only new operator we'll be looking at is &, which is used to start a command as a background process. We'll be revising redirectional operators, <, > and file descriptors.

Lastly we go a bit more into detail with the 'SIGHUP' signal. In short, this is a signal that is sent out when a terminal session is closed, which results in child processes being terminated. We'll discuss how one can make processes immune to the 'SIGHUP' signal, so that processes can continue even after we've closed the terminal. The commands introduced for this are screen, disown and nohup. Lastly we introduce the concept of daemon processes.

Parent and child processes

Processes are distinguished into parent, child and daemon processes, but for now we'll focus on parent and child processes. All processes have parent processes but not all parent processes have child processes. The relationship between the two is how you'd imagine; a child process is derived/spawned from its parent process. When a process starts the execution of a new program, it first makes a copy process of itself. In Linux we call this 'forking' and it is carried out by the system call fork(). You can think of system calls as an interface between applications and the kernel, where the shell is the intermediary translator between the two. The fork() is usually followed by a number of exec() system calls, which is what converts the child process into a new process.

You can see the Linux processes currently running in your terminal by using the command ps, which is short for 'process status'.

Prompt$          ps -ef        

Figure 8.1: Parent and child processes. In columns 1-8 there are UID (User ID), PID (Process ID) , PPID (Parent process ID's), C (Processor Utilization), STIME (Start time), TTY ('TeleTYpewriter'), TIME (CPU Time) and CMD (the actual command). It's not important to remember what all these columns mean, as you can always figure this out by going to the man page for ps. But just know that you can display different columns depending on the options that you use with ps.

A process is a child process of another process, if it's PPID (Parent process ID) is the same as that other processes PID (Process ID). By using different command options you can make ps display a lot of different column statistics on the processes running on your computer. You can often guess what the meaning of these columns are, but if you're in doubt you can always go the man page for ps. UID is short for 'user ID' and in this case there are only two instances of users; root and goodboy. (PID) is short 'process IDS' which are unique identification numbers, assigned to processes making it easier to target them. PPID is short for 'parent process IDS' which unique identification number of a process's parent process. Recall, that UNIX commands are in fact small programs, which is why ps -ef appears a process. Take note that the PPID for ps -ef is 4, which is the PID for -bash. This means that -bash is the parent process of ps -ef. The parent process for -bash is /init ro, which in turn has no parent processes. You can think of the init process as 'super parent process', which is the very first process to be run when you open a terminal. It should always have the PID, 1. For a more graphical view of this you can use the command pstree,

Prompt$          pstree        

which displays a tree of parent and child processes. The init process should always be the starting node of this tree.

Foreground and background processes

Processes can run in the foreground and background. Foreground processes is any command that you enter in the prompt, whereafter you have to wait for its completion before being able to enter a new command. Up till now you've only been executing commands as foreground processes. Unlike foreground processes, when a background process has been executed you don't have to wait for its completion before being able to issue a new command. Any command can be run as a background process by typing a space and '&' after the command,

Prompt$          [UNIX command] &        

As an example, we use the command, sleep, which is essentially a pause command that does nothing for a specified amount of time,

Prompt$          sleep 30 &        

will create a pause of 30 seconds as a background process, which you can view with the ps command. Now try to run sleep as foreground process,

Prompt$          sleep 60        

which will create of pause of 60 seconds. To exit this pause you have two choices; Press ctrl-d which will send a kill signal to any process running in foreground, terminating it immediately. Or you can press ctrl-z to send a stop signal to any process running in the foreground, pausing it immediately. If you chose the pause option you'll be able to see the process with ps ax, but its status will be T (Stopped). If you've paused the process you can restart it as a background process or foreground process.

Prompt$          bg %[job ID] Prompt$          fg %[job ID]        

which will restart the process as a background or foreground process respectively. You can see job ID's of currently running background processes by executing,

Prompt$          jobs        

which displays a list of active jobs. Jobs can be defined as processes that are initiated in the shell interactively by you, the user. Each job is assigned a job ID which the commands, bg and fg, use for targeting.

You can terminate a background process by sending it to the foreground and then terminating it with ctrl-d. But a more direct approach to terminating a background process is to use the kill command. It doesn't use job ID's and instead uses PID's,

Prompt$          kill          [PID]        

will terminate the process with corresponding [PID]. The kill command can actually be used to send to a multitude of signals to processes. You can see a list of all these different signals by using -L command line option,

Prompt$          kill -l        

By default the signal used by kill is the kill signal, 'SIGKILL', but you can also use kill to send a stop signal, 'SIGSTOP'.

Prompt$          kill -19 [PID]                  

will send a stop signal to the process with corresponding [PID].

Lastly, an alternative command to ps is top, the difference being that top provides a continuous representation of ongoing processes with an interactive command mode and ps only provides a snapshot of current processes. By typing,

Prompt$          top        

an interactive command mode and columns containing statistics of ongoing processes is displayed. The meaning of the columns is listed herunder.

  • PID: Unique process id.
  • PR: Priority of the task.
  • SHR: Represents the amount of shared memory used by a task.
  • VIRT: Total virtual memory.
  • USER: User name of owner.
  •  %CPU: CPU usage.
  • TIME+: CPU Time, similar to 'TIME'.
  • SHR: Shared Memory size (kb).
  • NI: Nice Value. Negative Nice Value imply high priority and positive Nice Value imply low priority.
  •  %MEM: Memory usage.

You can exit interactive command mode of top by pressing q. You can use the kill utility by pressing k while in the interactive command mode. You will then be prompted to enter which PID you want to send a signal to, whereafter you'll be prompted to enter what kind of signal you'd like to send. By default the signal is the kill signal, so if you don't enter any signal type and simply press enter, a kill signal will be sent. In figure 8.2 a kill signal is being sent to the process with the PID, 24, from the top interactive command mode.

Figure 8.2 The top command: The top command displays a continuous representation of ongoing processes. In this representation, we enter the kill utility by pressing k, whereafter we're prompted for a the PID we would like to send a signal to. In this case, we enter the PID, 24. Afterwards we'll be prompted for the signal type. By default this signal is a kill signal, so by entering nothing and a kill signal will be sent.

Redirecting outputs and providing necessary stdin for background processes

If a command requires additional stdin from the user or has some output, it will cause problems if it's run as a background processes. If a program run in the background requires additional stdin and doesn't receive it, the program will terminate. Furthermore, stdout and stderror from a background process needs to be redirected to somewhere else than the terminal. For example, when installing packages with apt there's a continuous stream of output regardless of whether it's run in the background or foreground. While this is being outputted we cannot continue working with other stuff in the terminal, which ruins the point of background processes.

So in order to run a program as a background process, you often need to redirect stdout and stderror to somewhere else. Here's one way,

Prompt$          [UNIX command] >          output_file 2> error_file          &        

In this command, file descriptors redirect both stdout and stderror from UNIX command to two separate files. Recall, that file descriptors correlate to the 3 standard streams; 0 for stdin, 1 for stdout and 2 for stderror. By default, output is redirected as stdout, which is why we write > instead of 1>'. If we don't care about the stdout and stderror we can redirect to what's called the null device, which all the data that's written to it.

Prompt$          [UNIX command] >          /dev/null          2>&1          &        

In this command, the stdout is used to redirect to '/dev/null/' with >, and the stderror is redirected, 2>, to the same place as the stdout, &1. Alternatively, you could have also typed,

Prompt$          [UNIX command] >          /dev/null          2>          /dev/null          &        

which will also redirect both stdout and stderror to the null device. If it helps, think of the null device as a blackhole where we through stuff we don't need.

We've dealt with the problem of redirecting stdout and stderror, but we still have to deal with the stdin. For instance, in the last section were we used apt to install packages, we needed to type in 'y' for installation of a package to continue. A solution to this, is simply to use the y option as shown in the last section.

Prompt$          sudo apt -y install          [package]          >          /dev/null          2>&1          &        

This command, will install [package] without asking for the additional 'y' confirmation and will direct all output to '/dev/null'. There might, however, not always be an option like the 'y option'. Therefore, we show another method where we use echo to pipe the stdin you need,

Prompt$          echo          'whatyouneedas_stdin'          |          sudo apt install          [package]          >          /dev/null          2>&1          &        

Also, you could create an <inputfile> and use redirectional operator for stdin, <, to feed its contents.

Prompt$          sudo apt install          [package]          <          <inputfile>          >          /dev/null          2>&1        

When you use sudo you'll be prompted to enter your password, which will grant you root privileges for 15 minutes. In these 15 minutes you won't be prompted again for your password when executing commands that require root privileges. If you run a command that requires root privileges as a background process while output is redirected to /dev/null and you don't have root privileges, the process will stop. The simplest solution to this problem is to run another command with root privileges prior to running your background process that requires root privileges. It doesn't matter what command you use to acquire these root privileges, it could for example be ls,

Prompt$ sudo ls > dev/null 2>&1  Prompt$ sudo [command that requires root privileges]        

A better way to do this is to utilize the fact that sudo by default doesn't read passwords from stdin, but directly from your keyboard. This is useful, if you need to run a command that requires both password and some stdin like 'y', because then you don't have to worry about 'y' being fed as your password.

Prompt$          echo          'y'          | sudo apt remove                    [package] > /dev/null 2>&1        

will ask you for your password which it receives from your keyboard. Subsequently, it's fed 'y' as stdin and all output is redirected to /dev/null.

It might be useful to know that you can actually feed your password by stdin by using -S option

Prompt$          echo          "Password" |          sudo -S          [command that requires root privileges]        

This command, will install [package] without asking for the additional 'y' confirmation and will direct all output to '/dev/null'. There might, however, not always be an option like the 'y option', so you could instead use echo to pipe the stdin you need.

Prompt$          echo          'whatyouneedas_stdin'          |          sudo apt install          [package]          >          /dev/null          2>&1          &        

Also, you could create an <inputfile> and use redirectional operator for stdin, <, to feed its contents.

Prompt$          sudo apt install          [package]          <          <inputfile>          >          /dev/null          2>&1        

When you use sudo you'll be prompted to enter your password, which will grant you root privileges for 15 minutes. In these 15 minutes you won't be prompted again for your password when executing commands that require root privileges. If you run a command that requires root privileges as a background process while output is redirected to /dev/null and you don't have root privileges, the process will stop. The simplest solution to this problem is to run another command with root privileges prior to running your background process that requires root privileges. It doesn't matter what command you use to acquire these root privileges, it could for example be ls,

Prompt$ sudo ls > dev/null 2>&1  Prompt$ sudo [command that requires root privileges]        

A better way to do this is to utilize the fact that sudo by default doesn't read passwords from stdin, but directly from your keyboard. This is useful, if you need to run a command that requires both password and some stdin like 'y', because then you don't have to worry about 'y' being fed as your password.

Prompt$          echo          'y'          | sudo apt remove                    [package] > /dev/null 2>&1        

will ask you for your password which it receives from your keyboard. Subsequently, it's fed 'y' as stdin and all output is redirected to /dev/null.

It's also useful to know that you can actually feed your password by stdin by using -S option

Prompt$          echo          "Password" | sudo -S [command that requires root privileges]        

Continuing processes after exiting terminal: screen, disown and nohup

Under normal circumstances, any child processes started are sent what's called 'SIGHUP' (short for signal hangup) when the terminal session ends, effectively terminating processes. In other words, if the computer or server you're working on crashes, ongoing processes will be terminated. This is obviously problematic and are 3 ways to avoid this; screen, disown and nohup.

When people talk about multiple screens in Linux, they're talking about running multiple terminal windows separate from each other. The processes run within these different terminal windows are not affected by the user logging of, and they're all equipped with a shell.

Prompt$ 'sudo screen -S          [screen_name]        

will start a new terminal window called [screen_name]. Within this terminal window you can start a lengthy process in the foreground, then quit the terminal window while keeping its shell running by pressing ctrl a-d. You don't have to redirect output as the output is directed to the terminal you started the process, which is the screen. Screens are quite useful if you're doing a lengthy proces and you're not sure what stdin it might need, so you want to be able to be able interact with the process.

You can read more about screens here:
Additional info on screens 1
Additional info on screens 2

As mentioned, the signal that is sent that terminates processes when terminal session ends, is called 'SIGHUP'. You can make processes inmmune to this signal by using the command disown, which will detach the process from the shells job list, so that the process is not sent a 'SIGHUP' signal when the terminal session ends. For example,

Prompt$          sudo bash -c          'apt-get -y install          [package]          >          /dev/null          2>&1 & disown'        

will install [package] as a child process separate from the terminal, and the installation of the package will therefore proceed even if the terminal is shut down.

Lastly, a very useful command that has similar function to disown is nohup. Unlike disown, the command nohup is defined by POSIX, which means that it works within most shells. We haven't really discussed what POSIX is. Essentially, POSIX represents a standard for the syntax of UNIX operating systems and command line shells, and ensures compatibility between them. It is, however, rarely the case that an OS is 'POSIX-certified', and most OS's are defined as 'Mostly POSIX-compliant'. For instance, there are some shells where disown doesn't work (tcsh, csh, dash and sh). Any command run with nohup will be immune to SIGHUP signaling, furthermore, nohup ignores all standard input and directs any output bound for the terminal to the file, <nohup.out>. This means that this command is not ideal for processes that require additional stdin.

Prompt$          nohup          [command]        

will execute [command], direct all output to <nohup.out> and ignore all stdin. Also, if the terminal ends, the 'SIGHUP' signal will be ignored and the process will not end.

Daemon processes

Daemon processes are difficult to characterize as the share many of the same characteristics as normal background processes have. They run in the background and are detached from the terminal, therefore not being affected by the closing of a terminal. The parent process of daemon processes is most often the init process, which means that daemons will most often have PPID value of 1. They're usually created by forking a child process, followed by an immediate exit of the process, however, they can also be created directly by the init process. User typically have no control over these processes. You can see all running daemon processes by typing,

Prompt$ ps -A        

which lists all ongoing UNIX processes. Except for the init process and a few others, daemon processes typically have the ending, 'd'. The output from executing ps -A is shown in figure 8.3. Here, there are 3 daemon processes which are underlined with red. Two of these are the init process and the third is what's called 'Secure shell server' process. The screen process has been underlined with orange to show that processes with a PPID value of 1, aren't necessarily a daemon. There are other daemons which won't show up unless you're using a Linux computer.

Figure 8.3 Ongoing processes, some of which are daemons: The figure shows the execution and output of the command, ps -A, which shows ongoing Unix processes. 3 daemon processes are underlined with red, two of which are init process process and the third 'Secure shell server' process. Processes with a PPID value of 1, such as the screen process underlined with orange, aren't necessarily daemons.

Command list

In the table below, we list this sections UNIX commands

UNIX Command Acronym translation Description
[Any command] & - Runs command as a background process
bg %[PID] bg and PID are short for background and process identification respectively Continues a stopped job in the background
fr %[PID] fr and PID are short for foreground and process identification. Continues a stopped job in the foreground
top [OPTION] - Displays all the processes running on your computer
ps [OPTION] Process status Reports a snapshot of current processes.
kill [OPTION] [PID] - Sends a signal to a process and by default this signal is to terminate the process.
history - Displays a list of commands you've previously executed commands.
screen - Used to create new terminal windows that are detached from each other. Child processes created within these new terminal windows are not affected if their parent process is terminated.
disown - Dissociates process from current terminal session.
nohup No hangup Used to run commands immune to hangups, ignoring stdin. By default output is redirected to <nohup.out>
pstree Process tree Display a tree of parent and child processes.

Exercise 1: Working with PIDs

1. Take a snapshot of current process and save the process information to a file. The process information should contain PID's and PPID's as a minimum.
2. In the file, replace the occurrence of bash with 'Hacked'.
3. Extract the process ID of the 'Hacked' process and have the output directed to your terminal.
4. Make a screen and exit it without closing it.
5. Extract its PID and have it redirected to your terminal.

Exercise 2:

sumsumanetur1960.blogspot.com

Source: https://teaching.healthtech.dtu.dk/unix/index.php/Processes;_foreground_and_background,_ps,_top,_kill_and_daemons