1. Overview

When we work on a Linux system, we often need to check what processes are running and how they affect the system’s performance. For that, we can use the ps command, which shows us various information about the processes.

But not all processes are the same. Some of them are part of the Linux kernel and do important things for the system, like managing hardware devices, scheduling, and so on. These are called kernel processes or kernel threads. They usually have a low ID and a square bracket around their name in the ps output.

Kernel processes are essential for the system’s operation, but they’re not usually the ones that cause problems or consume resources. Most of the time, we want to exclude them from our ps output and focus only on the non-kernel processes. Non-kernel processes are the ones that we or other applications start. They’re also called user processes.

In this tutorial, we’ll see how to use the ps command to display only the non-kernel processes on our Linux system.

2. Non-kernel Processes

Non-kernel processes, also known as user threads, are the processes initiated by users or applications on a Linux system. They can be either foreground processes, which depend on the user for input and output, or background processes, which run independently of the user.

Non-kernel processes have a significant impact on the system’s performance and resource utilization. They consume CPU time, memory, disk space, network bandwidth, and other resources. They can also interact with each other and with the kernel processes through various mechanisms, such as signals, pipes, and sockets.

Therefore, it’s essential to monitor and manage non-kernel processes. By doing so, we can achieve the following:

  • Identify and troubleshoot issues related to high CPU or memory usage, disk or network congestion, and process hanging or crashing.
  • Optimize the system’s performance and efficiency by adjusting the process priority.
  • Control the process execution by starting, stopping, suspending, resuming, or killing processes as needed.
  • Secure the system by preventing unauthorized or malicious processes from running or accessing sensitive data.

We might normally use the ps command to list processes, so let’s find out how to focus on non-kernel processes with it.

3. The ps Command

The ps command, short for Process Status, shows information about the running processes. It has many options and arguments that allow us to customize the output according to our needs.

The ps command accepts several types of options:

$ ps [OPTIONS]

Options include:

  • UNIX style options, preceded by a single dash ()
  • BSD style options, used without a dash
  • GNU long options, preceded by two dashes ()

We can mix different types of options, but we should be careful about possible conflicts. For example, ps -aux isn’t the same as ps aux. The UNIX standards require that ps -aux print all processes owned by a user named x, while ps aux will print all processes with a terminal.

However, if the user named x doesn’t exist, ps may interpret the command as the BSD style instead and print a warning.

In this article, we’ll mainly use the BSD style options, which are more concise and widely used.

3.1. -e and -f Options

One of the most common options for the ps command is -e, which tells ps to display all processes on the system. This option is equivalent to -A or –all.

Another common option is -f, which tells ps to display a full-format listing of the processes. This option shows more information than the default output, such as the process owner, parent process ID (PPID), start time, terminal name, and command arguments.

We can combine these two options to get a comprehensive view of all processes on our system:

$ ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 19:46 ?        00:00:02 /sbin/init splash
root           2       0  0 19:46 ?        00:00:00 [kthreadd]
root           3       2  0 19:46 ?        00:00:00 [rcu_gp]
root           4       2  0 19:46 ?        00:00:00 [rcu_par_gp]
root           5       2  0 19:46 ?        00:00:00 [slub_flushwq]
root           6       2  0 19:46 ?        00:00:00 [netns]
root           8       2  0 19:46 ?        00:00:00 [kworker/0:0H-events_highpri]
root          10       2  0 19:46 ?        00:00:00 [mm_percpu_wq]
root          11       2  0 19:46 ?        00:00:00 [rcu_tasks_kthread]
root          12       2  0 19:46 ?        00:00:00 [rcu_tasks_rude_kthread]
root          13       2  0 19:46 ?        00:00:00 [rcu_tasks_trace_kthread]
root          14       2  0 19:46 ?        00:00:00 [ksoftirqd/0]
root          15       2  0 19:46 ?        00:00:03 [rcu_preempt]
root          ...

The output consists of eight columns:

  • UID – user ID of the process owner
  • PID – process ID
  • PPID – parent process ID
  • C – processor utilization percentage
  • STIME – start time of the process
  • TTY – terminal name associated with the process
  • TIME – cumulative CPU time used by the process
  • CMD – command name and arguments

As we can see, this output includes both kernel and non-kernel processes. We can identify kernel processes by the square brackets around their names ([kthreadd], [rcu_gp], etc.). We can also notice that kernel processes have no user ID or terminal name.

3.2. Other Common Options

Besides -e and -f, there’re other common options to display processes:

  • -a – all processes except session leaders and processes not associated with a terminal
  • -u – user-oriented format, which shows more information about CPU and memory usage
  • -x – processes without a controlling terminal, such as daemons and background jobs
  • -l – long format, which shows more information about process priority, nice value, and status
  • -o – user-defined format, which allows us to specify the columns and their order
  • -C – processes by command name
  • -U – processes by user name or ID
  • -p – processes by process ID

We can combine these options to get different views of the processes on our system. For example, we can use ps aux to get a user-oriented view of all processes, including those without a terminal:

$ ps aux
root           1  0.0  0.1 167296 12356 ?        Ss   19:46   0:02 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    19:46   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   19:46   0:00 [rcu_gp]

The output consists of eleven columns. The %CPU is the percentage of CPU used, and the %MEM is the percentage of RAM used by the process. Also, VSZ is the virtual memory size of the process in kilobytes and RSS is the amount of physical memory used by the process in kilobytes.

3.3. Using ps to Display Kernel Processes

As we saw earlier, kernel processes are marked with square brackets around their names. We can use this feature to filter out kernel processes using tools like grep:

$ ps aux | grep '\['
root           2  0.0  0.0      0     0 ?        S    Jun08   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   Jun08   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   Jun08   0:00 [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I<   Jun08   0:00 [slub_flushwq]

4. Displaying Non-kernel Processes With ps

So far we’ve learned how to use ps command to display various information about the running processes on our system. However, we also saw that the output of ps includes both kernel and non-kernel processes, which may not be what we want.

Now let’s see how to use the ps command to display only the non-kernel processes on our system.

4.1. Excluding the kthreadd Process and Its Child

kthreadd is a kernel thread responsible for creating and managing other kernel threads. It has its PID to be 2 because it started right after init is created. All kernel threads have PPID of kthreadd, which is 2.

We can exclude all kernel threads and display only the non-kernel processes:

$ ps --ppid 2 -p 2 --deselect
    PID TTY          TIME CMD
      1 ?        00:00:02 systemd
    269 ?        00:00:00 systemd-journal
    309 ?        00:00:00 systemd-udevd
    622 ?        00:00:05 systemd-oomd

The output shows only non-kernel processes, which have neither kthreadd as their parent process nor kthreadd itself.

4.2. Using grep Command

As we’ve discussed, kernel processes are enclosed in brackets. We can pass the output of ps to the grep command to filter out lines that end with a closing bracket:

$ ps auxf | grep -v ]$
root           1  0.0  0.1 167236 11936 ?        Ss   09:21   0:02 /sbin/init splash
root         269  0.0  0.2  48780 17664 ?        S<s  09:21   0:00 /lib/systemd/systemd-journald
root         309  0.0  0.0  26856  6788 ?        Ss   09:21   0:00 /lib/systemd/systemd-udevd
systemd+     622  0.2  0.0  14824  5880 ?        Ss   09:21   0:10 /lib/systemd/systemd-oomd
systemd+     626  0.0  0.1  26056 13856 ?        Ss   09:21   0:01 /lib/systemd/systemd-resolved

The output shows only non-kernel processes and the columns are labeled based on the options we passed to the ps command.

This method might result in omitting some unwanted entries having names ending with a bracket, but it’s very unlikely.

4.3. Displaying Processes With Non-zero Virtual Memory Size

One way to recognize kernel processes is that they don’t use any user memory, so the VSZ field is zero. This approach also catches zombies, which are processes that have terminated but haven’t yet been reaped by their parent process.

Let’s use this method to eliminate kernel processes from the display:

$ ps -eo pid,vsz,stat,args | awk '$2 != 0'
      1 167288 Ss   /sbin/init splash
    269  48840 S<s  /lib/systemd/systemd-journald
    311  26932 Ss   /lib/systemd/systemd-udevd
    636  14824 Ss   /lib/systemd/systemd-oomd

We specified the columns to display so that we can be able to pass the field into the awk command. This command and option display all processes in a user-defined format with PIDVSZSTAT, and ARGS columns. The awk command filters out lines that have zero in the second field (VSZ).

Also, we can exclude the zombies process from the output:

$ ps -eo pid,vsz,stat,args | awk '$2 != 0 && $3 != "Z"'

4.4. Displaying User Processes

User processes are processes initiated by a regular user account and run in user space. They have no special access to the processor or to files on the system that don’t belong to the user who launched the process.

To monitor user processes, we can specify a user name as an argument to -u to filter the output by a specific user:

$ ps -u abdulhameed
    PID TTY          TIME CMD
   3759 ?        00:00:00 systemd
   3760 ?        00:00:00 (sd-pam)
   3767 ?        00:00:00 pipewire

The output shows only the processes owned by abdulhameed.

5. Conclusion

In this article, we’ve learned how to use the ps command to display only the non-kernel processes on our Linux system. We’ve seen that kernel processes are special processes that are created and managed by the Linux kernel, and that they can be identified by their PIDPPIDCMD, or VSZ fields.

We also explored different methods to filter out kernel processes from non-kernel processes.

The ps command is a powerful tool that can help us monitor and manage the processes on our Linux system. By knowing how to use it properly, we can improve our understanding and control of our system and applications. Also, we can diagnose and fix process-related problems.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.