docker: Finding an alternative to the ps command using the /proc filesystem

2 min read

On some container we might find the nasty surprise that the ps command is no available:

$ ps
sh: 1: ps: not found

If we need to check the processes (and it's arguments) we'll need to resort to the /proc filesystem

On a Linux system (or container) each process has a directory under the /proc system containing info about it. One of the files is the cmdline that is is a zero separated list of arguments. We can write a very easy script that prints the PID and it's command line string like follows:

for proc in /proc/*/cmdline; do echo $(basename $(dirname $proc)) $(cat $proc | tr "\0" " "); done

This way we get something similar to a ps that can help us checking the processes that are running inside that container:

$ for proc in /proc/*/cmdline; do echo $(basename $(dirname $proc)) $(cat $proc | tr "\0" " "); done
1 java -jar example.jar -app.jdbc.url=jdbc:postgresql://testdb.8mj1c11cbraa.eu-west-1.rds.amazonaws.com:5432/ampa
10 tail -F ./logs/demo.log
(...)
490 sh
506 bash
self cat /proc/self/cmdline
thread-self cat /proc/thread-self/cmdline

It will also show some files that are not actually processes but references to processes:

$ for proc in /proc/*/cmdline; do echo $(basename $(dirname $proc)) $(cat $proc | tr "\0" " "); done
1 java -jar example.jar -app.jdbc.url=jdbc:postgresql://testdb.8mj1c11cbraa.eu-west-1.rds.amazonaws.com:5432/ampa
10 tail -F ./logs/demo.log
(...)
490 sh
506 bash
self cat /proc/self/cmdline
thread-self cat /proc/thread-self/cmdline

So if we are really picky about it we can rewrite it to:

$ for proc in /proc/[0-9]*/cmdline; do echo $(basename $(dirname $proc)) $(cat $proc | tr "\0" " "); done
1 java -jar example.jar -app.jdbc.url=jdbc:postgresql://testdb.8mj1c11cbraa.eu-west-1.rds.amazonaws.com:5432/ampa
10 tail -F ./logs/demo.log
(...)

Posted on 16/12/2021

Categories