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 topgrep
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