How to Exclude grep Process When Using ps Command in Unix/Linux Systems


3 views

When working with process management in Unix/Linux systems, a frequent annoyance occurs when trying to filter processes with ps and grep:

$ ps aux | grep django
user     28006  0.0  0.1 123456  7890 ?        S    10:00   0:01 /usr/bin/python bin/django celeryd
user     53780  0.0  0.0   1234   567 pts/1    S+   10:05   0:00 grep --color=auto django

The grep process itself appears in the results because its command line contains the search pattern. This creates noise when you're trying to inspect running services.

Here are proven ways to filter out the grep process:

# Method 1: Using character class in pattern
ps aux | grep '[d]jango'

# Method 2: Using pgrep (preferred modern approach)
pgrep -fl django

# Method 3: Using ps with --no-header and grep -v
ps -ef --no-header | grep django | grep -v grep

The [d]jango pattern works because:

  • The grep process command line becomes grep [d]jango
  • The regex [d]jango matches the literal "django"
  • But grep [d]jango doesn't match [d]jango

Consider these specialized process lookup tools:

# Using pgrep
pgrep -f django

# Using pstree (shows process hierarchy)
pstree -p | grep django

# Using htop interactive filter
htop --filter=django

For production scripts, I recommend:

#!/bin/bash
# Safe process counting
count=$(pgrep -f django | wc -l)
if [ $count -eq 0 ]; then
    echo "No django processes running"
else
    echo "Found $count django processes"
fi

Every Unix/Linux user has encountered this situation when running process searches:

$ ps aux | grep django
user   28006  0.0  1.2 123456 7890 ?        S    Feb10   1:12 /usr/bin/python bin/django celeryd --beat
user   51393  0.0  1.4 234567 8910 ?        S    Feb10   1:45 /usr/bin/python bin/django celeryd -l INFO
user   53780  0.0  0.0   1234  567 pts/1    S+   12:34   0:00 grep --color=auto django

The grep command appears in the output because it temporarily exists as a process during the pipeline execution. The ps command captures all running processes, including the grep command itself that's searching for the pattern.

Method 1: Using grep's Inverse Search

The simplest solution is to exclude the grep command itself:

ps aux | grep [d]jango

This works because [d]jango matches "django" but grep [d]jango doesn't match itself.

Method 2: Using pgrep

For modern systems, pgrep is a cleaner alternative:

pgrep -a django

Method 3: Using Process Substitution

Bash users can use process substitution to avoid the grep process:

ps aux | grep -v grep | grep django

Using awk for Precision

For more complex filtering, combine with awk:

ps aux | awk '/django/ && !/grep/ {print $0}'

Systemd Environments

On systems using systemd:

systemctl list-units --type=service | grep django
  • Don't use grep -v grep when grepping for processes containing "grep"
  • Be careful with simple pattern matching that might match unintended processes
  • Consider using full process paths when possible for more precise matching

For frequent process monitoring, consider these optimized approaches:

# Using --no-header to skip column names
ps --no-headers -o cmd -C python | grep django

# Using pstree for process hierarchy
pstree -p | grep django