How to Filter Linux ps Command Output by Both User AND Command for Precise Process Identification


9 views

When working with process management in Linux, the ps command's filtering options don't always behave as expected. While ps -u username shows all processes for a specific user and ps -C commandname displays all instances of a particular command, combining them with ps -u username -C commandname surprisingly returns a union (OR) of both conditions rather than the intersection (AND) that most administrators expect.

Here are several effective approaches to achieve the desired AND filtering:

Method 1: Piping to grep

ps -u username | grep commandname

Or more precisely:

ps -u username -f | grep "[c]ommandname"

The bracket trick prevents the grep process itself from appearing in results.

Method 2: Using pgrep (preferred for scripting)

pgrep -u username commandname

Or for full process information:

pgrep -u username -a commandname

Method 3: Advanced ps Formatting

ps -u username -o pid,comm | awk '$2 == "commandname" {print $1}'

Scenario: Find all nginx processes owned by user 'www-data'

ps -u www-data -f | grep "[n]ginx"

Scenario: Get PID of specific python script running under user 'deploy'

pgrep -u deploy -f "my_script.py"

The pgrep method is generally fastest as it queries the proc filesystem directly. The grep approach works well for interactive use but may be slower for systems with many processes. For scripts that need to run frequently, consider caching the results or using process monitoring tools instead.

  • Commands with spaces: Use pgrep -f for full command matching
  • Zombie processes: Add -x flag to pgrep for exact matching
  • Short-lived processes: Combine with watch for monitoring

When working with process management in Linux, the ps command's filtering behavior can sometimes be counterintuitive. The key issue arises when combining multiple filters:

# This uses OR logic (shows processes owned by user1 OR matching command1)
ps -u user1 -C command1

To properly filter processes that match BOTH the user AND command criteria, we need to chain the filters correctly. Here are three effective methods:

Method 1: Using grep with ps

ps -u user1 -f | grep '[c]ommand1' | awk '{print $2}'

Breaking this down:
- ps -u user1 -f lists all processes for user1 with full format
- grep '[c]ommand1' matches the command (using bracket trick to exclude grep itself)
- awk '{print $2}' extracts just the PID

Method 2: Using pgrep

pgrep -u user1 command1

This is the simplest solution when available, as pgrep naturally combines user and command filters with AND logic.

Method 3: Using ps with Custom Formatting

ps -o pid= -u user1 -C command1

The -o pid= specifies we only want PID output, while -u and -C filters apply as AND conditions in this format.

Let's look at some real-world scenarios:

Finding Apache Processes for User www-data

ps -o pid= -u www-data -C apache2

Identifying Specific Python Scripts

pgrep -u deployer -f "python3 /opt/app/main.py"

Be aware of these special situations:

  • When dealing with command arguments, use -f flag with ps or -f with pgrep
  • For processes with spaces in their names, use quotes around the command
  • Some older systems might not support all these options - check your man pages