How to Retrieve the Full Command Line of a Process by PID in Linux


2 views

When debugging or monitoring processes in Linux, you might need to check the exact command line used to launch a process. While /proc/${PID}/cmdline provides this information, it has a significant drawback: it replaces spaces with null characters (\0), making the output difficult to read.

Here are several reliable ways to retrieve the full command line with proper formatting:

1. Using ps Command

The simplest method is using ps with the -f or -ww flag:

ps -f -p ${PID}
ps -ww -p ${PID}

The -ww option ensures unlimited width output, showing the complete command.

2. Reading /proc/${PID}/cmdline with tr

You can process the cmdline file to replace null characters with spaces:

cat /proc/${PID}/cmdline | tr '\0' ' '
# Or more concisely:
tr '\0' ' ' < /proc/${PID}/cmdline

3. Using xargs -0

Another approach using xargs:

xargs -0 < /proc/${PID}/cmdline

Let's look at some practical implementations:

Bash Function for Easy Access

get_cmdline() {
    if [ -z "$1" ]; then
        echo "Usage: get_cmdline PID"
        return 1
    fi
    tr '\0' ' ' < /proc/"$1"/cmdline
    echo
}

Python Implementation

For more complex processing, here's a Python script:

import os

def get_command_line(pid):
    try:
        with open(f'/proc/{pid}/cmdline', 'rb') as f:
            return f.read().replace(b'\x00', b' ').decode()
    except FileNotFoundError:
        return f"Process {pid} not found"

print(get_command_line(1234))  # Replace 1234 with your PID
  • Some processes might modify their own command line arguments
  • Zombie processes won't have accessible cmdline information
  • For containers or namespaces, you might need additional steps

For scripts that need to check many processes, ps might be slower than reading directly from /proc. Here's a quick benchmark:

time for i in {1..1000}; do ps -p $$ >/dev/null; done
time for i in {1..1000}; do cat /proc/$$/cmdline >/dev/null; done

When debugging or monitoring Linux processes, you often need to examine the exact command that launched a specific process. While the PID (Process ID) gives you access to process information through /proc, the standard /proc/${PID}/cmdline approach presents a readability challenge as it replaces spaces with null characters.

Here's what happens when you directly read from cmdline:

cat /proc/1234/cmdline
# Output: python3\0my_script.py\0--verbose\0--log-level\0debug\0

The null characters (\0) make the output difficult to parse visually, especially for complex commands with multiple arguments.

Here are several effective methods to properly view the command line:

Method 1: Using tr Command

Replace null characters with spaces:

tr '\\0' ' ' < /proc/1234/cmdline
# Output: python3 my_script.py --verbose --log-level debug

Method 2: Using ps Command

The most straightforward approach:

ps -p 1234 -o cmd=
# or for full command with arguments:
ps -fp 1234

Method 3: Using xargs

Clean formatting with xargs:

xargs -0 < /proc/1234/cmdline

Method 4: Python Script

For more complex parsing needs:

import os
def get_command_line(pid):
    try:
        with open(f"/proc/{pid}/cmdline", "rb") as f:
            return f.read().replace(b'\\0', b' ').decode()
    except FileNotFoundError:
        return f"Process {pid} not found"

print(get_command_line(1234))

For system monitoring tools, consider these approaches:

# Get all process commands (similar to ps aux)
find /proc -maxdepth 1 -type d -name '[0-9]*' \
    -exec sh -c 'echo {}; xargs -0 < {}/cmdline; echo' \\;

Remember that:

  • Zombie processes won't have accessible cmdline
  • Some processes might intentionally obfuscate their cmdline
  • Permissions are required to read other users' process information