Skip to content
shellhacks.dev
Linux

Get a process's command line

Read a running process's full command line from /proc/PID/cmdline. The arguments are separated by NUL bytes, so split them with xargs -0 and not tr.

1 min read
Summarize in AI

ps truncates long command lines and loses the boundaries between arguments, but the kernel keeps the exact list.

Shell
python3 -c 'import time; time.sleep(60)' first "second arg" &
pid=$!
tr '\0' ' ' < /proc/$pid/cmdline; echo
xargs -0 printf '[%s]\n' < /proc/$pid/cmdline
kill $pid
Text
python3 -c import time; time.sleep(60) first second arg
[python3]
[-c]
[import time; time.sleep(60)]
[first]
[second arg]

The kernel exposes the argument vector of a process in /proc/PID/cmdline as the strings joined by NUL bytes, as the proc manual explains. Turning the NULs into spaces, as the first command does, merges "second arg" into two words. xargs -0 splits on the NULs, so each argument stays whole.

A process can rewrite its own argv after it starts, so what you read may differ from what was typed. The file is empty for a zombie and for kernel threads, and it is readable by any user unless the system mounts /proc with hidepid. Parsing it is Linux only.

Share

More snippets

Linux

Always use -a with -G

Add a user to a group with usermod -aG. Without -a the -G option replaces the whole supplementary group list, and the user silently loses every other group.

1 min read
Linux

Run a command with a clean environment

Run a command with an empty environment using env -i, then add back only the variables you pass. It reproduces what cron or a minimal container sees.

1 min read
Linux

Convert a date string to a timestamp

Convert a date string to a Unix timestamp with GNU date -d 'string' +%s. The zone is the one in TZ unless the string names one, so set it explicitly.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.