Unless explicitly specified, process selection options are additive, i.e. the flags below are logically OR'ed.
Flag |
Usage |
-a |
select all processes except both session leaders and processes not associated with a terminal |
a |
- select all processes with a terminal (tty) (by actually lifting the BSD-style "only yourself" restriction)
- with x : select all processes
|
-A or -e |
select All processes |
-C commandList |
select processes whose executable name is given in commandList |
--cols n --columns n |
set screen width to n columns |
f |
forest : ASCII-art process hierarchy |
-f |
full-format listing |
-F |
extended full-format listing. Implies -f |
l |
display BSD long format |
-L |
- show threads
- with -f, show columns :
- LWP : thread ID
- NLWP : number of threads
|
o formatSpecString
-o formatSpecString
--format formatSpecString |
introduces the output format specifiers |
-O formatSpecString
(uppercase "o")
|
same as -o but preloaded with some default columns. Identical to -o pid,format,state,tname,time,command |
p pidlist -p pidlist --pid pidlist |
select by PID |
--ppid n |
select processes which parent process ID is n |
-T |
display PID of Threads, aka SPID |
u |
display user-oriented format |
U userId
-u userId
--user userId |
select processed owned by userId (user name orUID) |
Z or -M |
add a column of security data (for SELinux) |
ps may display the user's uid instead of the user's name if the username is longer than 7 characters.
Output column headers :
Some column headers are sometimes cryptic, and single-letter values are hard to find in the
man. To get the full list :
- LANG=C man -P 'less -p "^STANDARD FORMAT SPECIFIERS"' ps
- scroll
Header |
Usage |
output by command |
Details |
C |
CPU usage % |
ps -eF | head -10 |
integer value of the percent usage over the lifetime of the process |
F |
process flags |
ps -l | head -10 |
- 0 : no flag set
- 1 : forked but didn't exec
- 4 : used super-user privileges
|
S |
process state |
ps -l | head -10 |
values |
Specifier |
Usage |
args |
displays the command that is executing, with all its arguments |
comm |
displays the name of the command that is executing (the binary ?) |
etime |
elapsed time since the process was started : [[dd-]hh:]mm:ss |
etimes |
elapsed time since the process was started, in seconds |
gid |
EGID of the process. See uid |
lstart |
date + time the process was started : Fri Aug 21 23:32:21 2015. |
lwp |
ID of the light weight process (thread) |
nlwp thcount |
number of light weight processes (threads) |
pcpu %cpu |
ratio : cputime of the process / realtime |
pid |
PID of the selected process |
ppid |
PID of the parent of the selected process |
pmem %mem |
ratio : RSS / physical memory |
sgi_p |
ID of the processor currently executing the process. Will display * if the process is not currently being executed |
start |
If the process was started less than 24 hours ago, display its start time in 24h:mm:ss format. Otherwise, display the start date formatted like Aug 21. |
start_time |
If the process was started today, display its start time in 24h:mm format. Otherwise, display the start date formatted like Aug21. |
state |
state of the process :
|
time cputime |
cumulative CPU time, [DD-]HH:MM:SS format |
uid |
EUID of the process
ps -o comm,user,uid,gid
|
user euser uname |
name of the user owning the process |
vsize vsz |
virtual memory (=SWAP) size of the specified process, in KiB (needs details) |
The output format can be specified in the form :
You can change a column header by specifying a custom value for the selected
specifier :
ps -o pid='Process_ID',tt=TTY,time,comm=Command
If the custom value is empty, no header is displayed, which is convenient to output process names only : ps -o comm=
List all running processes :
- ps -elf
- ps aux / ps faux (Their output is not equivalent as both command don't return the same amount of results (check it with : watch -n 1 -d 'echo "-elf : "$(ps -elf | wc -l);echo " aux : "$(ps aux | wc -l)'))
- pstree
Display process tree :
ps -axfo pid,ppid,uname,cmd
View the hierarchy of a specific process (aka "climb" the process tree) :
pidToInvestigate=30845; showPidDetails() { local pid=$1; ps -o ppid,pid,args "$pid"; }; getPpid() { local pid=$1; ps -o ppid= -p "$pid" | awk '/[0-9]+/ {print $1}'; }; investigatePid() { local pid="$1"; ppid=$(getPpid "$pid"); showPidDetails "$ppid"; [ "$ppid" -ne '1' ] && investigatePid "$ppid"; }; showPidDetails "$pidToInvestigate"; investigatePid "$pidToInvestigate"
Display process tree :
ps -axfo pid,ppid,uname,cmd
List the 10 most CPU-hungry processes (source) :
Find the amount of RAM (in KiB) used by a process :
- normal command :
- ps -C firefox-esr -o comm,rss
- with the
=
hack to hide the header line :
- ps -C firefox-esr -o rss=
- in MiB :
-
- ps -o comm,rss | awk '/firefox-esr/ {print $2 / 1024}'
- echo "$(ps -C firefox-esr -o rss=) / 1024" | bc
- let ramUsed=$(ps -C firefox-esr -o rss=)/1024; echo $ramUsed
Get extra information using the output formatting specifiers :
ps -p942 -o %cpu,%mem,lwp,nlwp,sgi_p,start,start_time,vsz,wchan,rss,user
Find zombies:
- ps -e -o pid,ppid,args,state | grep -E 'Z$'
- pgrep -r Z
More about zombies (source) :
Zombie processes are
already dead, so they can't be killed. They are the consequence of malfunction (or programming defect) in their
parent processes.
When a process finishes :
- its status changes to EXIT_ZOMBIE
- its parent process
- is notified of the termination of a child process by receiving the SIGCHLD signal
- is expected to read the child process' exit status and stats with
wait()
. During that time, the child process is a zombie.
- then the zombie process is completely removed from memory and from the process table
This happens almost instantly, which is why in
normal
conditions we may see no
zombie processes.
Consequence of having zombies :
The footprint of a zombie is only the memory required to store its process descriptor, so zombies have no impact on system resources or performance : a few zombies are harmless. The only impact they _could_ have is that every zombie has its own PID, and PIDs are limited to 32768 (cat /proc/sys/kernel/pid_max). So an uncontrolled growth of the zombie population may exhaust the pool of PIDs.
Getting rid of zombies :
Zombies are dead processes. You cannot kill the dead, but here are a few things you can try :
- notify the parent process that one of its children died :
- kill -s SIGCHLD PID_parentOfZombieProcess
- kill -s SIGCHLD $(ps -o ppid= -p PID_zombieProcess)
this has already been done automatically —and failed— so it's unlikely it will change anything, but it's a safe #1 thing to try
- kill the parent process
- the init process inherits the zombie process
- init periodically runs
wait()
, cleaning up its own zombie children
How to find the full path of a command returned by ps ?
- ps -eF | awk '/binary/ {print $2}' | xargs -I pattern ls -l /proc/pattern/exe
- The command above will show a ls: cannot access /proc/whateverPid/exe: No such file or directory because awk matches its own process, which doesn't exist anymore once piped to ls via xargs. To workaround this :
- If there are MANY processes (possibly) running the same binary (e.g. when running Oracle), you can check this by sorting the displayed binaries :