How to Use pgrep/pidof for Filtering Processes with Specific Command-Line Arguments


2 views

html

When working with process management in Linux systems, we often need to target specific instances of a running process based on their full command-line arguments. The standard pidof or pgrep commands will return all matching processes by name, which isn't sufficient when you need to target a particular instance with specific parameters.

Consider this common situation in process management:

657 ?        S      0:00 processname software
658 ?        S      0:00 processname demo
659 ?        S      0:00 processname test

Standard commands would return all three PIDs:

$ pidof processname
657 658 659

The pgrep command with the -f flag allows matching against the full command line:

$ pgrep -f "processname test"
659

For more complex scenarios, consider these patterns:

# Case insensitive matching
pgrep -f -i "processname TEST"

# Full regex pattern matching
pgrep -f "^processname test$"

# Combining with other utilities
pgrep -f "processname test" | xargs ps -fp

When using these techniques:

  • The -f flag makes pgrep match against the entire command line
  • Quotes are important to handle spaces in arguments
  • For production scripts, always validate the output
  • Consider using -l flag to list process names for verification

While less flexible, pidof can be combined with other tools:

pidof processname | xargs -n1 ps -p | grep "test" | awk '{print $1}'

However, the pgrep solution is generally more efficient and reliable.


When managing processes on Linux systems, we often need to target specific instances among multiple processes sharing the same name but having different command-line arguments. The standard pidof and pgrep commands return all matching PIDs by default, which isn't always what we need.

Consider this typical process listing:

657 ?        S      0:00 processname software
658 ?        S      0:00 processname demo
659 ?        S      0:00 processname test

The standard approaches have these limitations:

pidof processname  # Returns 657 658 659
pgrep processname  # Returns 657 658 659

These commands don't distinguish between the different argument variations.

The most effective solution is to use pgrep's -f flag which matches against the full command line:

pgrep -f "processname test"  # Returns just 659

Here are some practical examples demonstrating the power of this approach:

# Find nginx worker processes with specific configurations
pgrep -f "nginx: worker process -c /etc/nginx/special.conf"

# Locate Python scripts with specific module imports
pgrep -f "python.*import analyzer"

# Identify Java processes running particular JAR files
pgrep -f "java.*myapp\.jar.*--profile=production"

For systems without pgrep or when needing more complex matching:

ps -ef | grep "processname test" | grep -v grep | awk '{print $2}'

To actually send a HUP signal to our target process:

pkill -HUP -f "processname test"

Or if you need the PID for other operations:

target_pid=$(pgrep -f "processname test")
kill -HUP $target_pid

When using these techniques:

  • Be aware of special characters in your command patterns
  • Consider quoting your search patterns to prevent shell interpretation
  • Test your patterns with pgrep -a first to verify matches
  • Remember that -f matches the full command line including arguments

While pgrep -f is convenient, it's slightly slower than basic pgrep as it must examine the full command line of each process. For performance-critical scripts, consider more specific matching patterns.