Linux/Unix: Finding all commands on the system📄 BetterWays.dev wiki page | 🕑 Last updated: Dec 23, 2022
I recently needed a list of all available commands on the system. Here are a few ways you can achieve that.
Since the PATH environment variable contains a list of directories with executable files, we could start by iterating over files in those directories, filtering them, and caching the result, but your shell is typically already doing all that job (in a pretty efficient way).
If you're using bash,
compgen is a handy built-in command, which can provide us with the data that is used for the auto-completion feature.
We can get list of all command names by providing the
And we can easily sort the result:
compgen -c | sort
zsh that doesn't work out of the box, but you can install the completion system with
compinstall. You can enable it with something like:
autoload -Uz bashcompinit bashcompinit
This will provide you with a
compgen command which works similarly to the bash version.
If your directories in $PATH are relatively clean (containing no extra files), the solution could be as simple as this:
IFS=:; ls $PATH | sort -u
Note: Since $PATH uses a double colon as a directory separator, we can't give it directly to
ls. Instead of manipulating the string with something like
sed, I'm using
IFS variable to change the standard input field separator (more info: Linux/Unix: Understanding IFS (Input Field Separators)).
In practice, directories in $PATH aren't always super clean, so instead of
ls, we can use
find to filter only executable files:
IFS=:; find $PATH -type f -executable -maxdepth 1 -print | sort -u
Note: if you're using non-GNU version of find, you'll have to use something like
-perm +111 instead of
And since we're only interested in commands, and
find doesn't support returning only the last part of the path, we need to do that ourselves:
IFS=:; find $PATH -type f -executable -maxdepth 1 -print | sed 's|.*/||' | sort -u
There's a nice util called
stest (part of "suckless" tools) which we can use here instead of
IFS=:; stest -flx $PATH | sort -u
stest is usually a part of the
suckless-tools package, depending on the distro:
# deb-based apt install suckless-tools # rpm-based dnf install dmenu # Arch pacman -S dmenu