compgen: An Awesome Command To List All Linux Commands

Ever want to list all the Linux commands (including bash shell aliases and functions) you could run on the server/workstation? Look no further. Try compgen command to see possible Bash completions, function names, builtin-commands and more depending on the options under Linux.

The compgen is bash built-in command and it will show all available commands, aliases, and functions for you. This command works under Linux, macOS, *BSD and Unix-like system when Bash shell is installed. This command is intended to be used from within a shell function generating possible completions. If the optional CLI argument (WORDS) is supplied, it matches against the given WORDS.

Advertisement

compgen command in Linux syntax

The syntax is as follows for the command:
$ compgen option
$ compgen option arg

Let us see some common examples of the compgen:

compgen Linux command examples

To list all the commands available to you, enter:
$ compgen -c
Here is what I see:

ls
if
then
else
elif
fi
....
mahjongg
sol
gtali
sl-h
gnobots2
gnotravex
iagno
fortune
gnect
gnome-sudoku
LS
glchess
gnuchess
gnuchessx

Counting commands on your Linux or Unix system

You can search or count the commands using the grep command and wc command:

# Search it
compgen -c | grep find
 
# Count it
compgen -c | wc -l
 
# Print it
echo "$USER user can run $(compgen -c | wc -l) commands on $HOSTNAME."
## OR ##
printf "$USER user can run $(compgen -c | wc -l) commands on $HOSTNAME.\n"

Here is how results looks with the help of echo command or printf command:

vivek user can run 3436 commands on wks01.

To list all the bash shell aliases available to you, enter:
$ compgen -a
Sample outputs:

..
...
....
.....
.4
.5
bc
cd..
chgrp
chmod
chown
cp
dnstop
egrep
ethtool
fastping
fgrep
grep
iftop
l.
ll
ln
ls
mcdflush
mcdshow
mcdstats
mount
mv
pscpu
pscpu10
psmem
psmem10
rm
tcpdump
update
updatey
vnstat
wget
which

See 30 awesome handy bash aliases for more information. Other options are as follows:

########################################
# Task: show all the bash built-ins
########################################
compgen -b
########################################
# Task: show all the bash keywords
########################################
compgen -k
########################################
# Task: show all the bash functions
########################################
compgen -A function

Putting it all together:

compgen  -abckA function
 
##  It doesnt get much better than this
compgen  -abckA function | less
compgen  -abckA function | grep -i --color searchStringHere

Summing up

You learned about compgen bash built-in, which is used to list all Linux and Unix commands on the server. Our bash shell offers various built-in commands to manipulate the programmable completion facilities. For example, we can specify how arguments to each name should be completed using the complete command. In other words, we use both compgen and complete together.

compgen and complete command examples

Consider the following simple script:

#!/bin/bash
# Name: test.sh
# Purpose: Demos compgen and complete
# Author: Vivek Gite, under GPL v2.x+
# ------------------------------------------
 
# My default interface
if_default="br0"
 
# Help
USAGE="usage: $0 -d -h -i -r -H"
 
# CLI args
# -d for date
# -h for hostname
# -i for IP address
# -r for routing
# -H get help
# -----------------------------
while getopts :dhirH opt_char
do
case $opt_char in
	d) echo "Date: $(date)";;
	h) echo "Hostname: $HOSTNAME";;
	i) echo -e "IP for $if_default interface\n $(ip addr show $if_default)\n";;
	r) echo -e "Default routing for $HOSTNAME:\n $(ip route show)\n";;
	H) echo "$USAGE";;
	\?)
	echo "$OPTARG is not a valid option."
	echo "$USAGE";;
esac
done

You can run it as follows:
$ ./test.sh -d
$ ./test.sh -i
$ ./test.sh -h
$ ./test.sh -Y

Now I can add programmable bash completion to auto-complete the command sequence for the ./test.sh as follows:

# Type the following function at Bash 
#
#  By convention, the function name starts with an underscore _
_test_sh(){
  # Pointer to current completion word. By convention, it's named "cur" but this isn't strictly necessary.
  local cur
  # Array variable storing the possible completions.
  COMPREPLY=()   
  cur=${COMP_WORDS[COMP_CWORD]}
  # Use the compgen here to specific the ./test.sh CLI option
  case "$cur" in
    -*) COMPREPLY=( $( compgen -W '-d -h -i -r -H' -- $cur ) );; #   Generate the completion matches and load them into $COMPREPLY array.
  esac
 
  return 0
}

Use the -F option to call _test_sh() that specify how arguments are to be completed for the ./test.sh:
$ complete -F _test_sh ./test.sh
Test it by typing the ./test.sh and then pressing the [Tab] key to auto-complete the command sequence. For instance:
$ ./test.sh -[TAB]

Getting help about the compgen and complete command

Both of these commands have other important options. Hence, Use the man command/info command or help command as follows:
$ man bash
$ help complete
$ help compgen

compgen command in Linux and Unix

compgen command help options (click to enlarge)

🥺 Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🤠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

11 comments… add one
  • Curtis Jul 19, 2012 @ 12:31

    Here’s a pointless script! If you have `whatis` enabled, you can run this script to tell you what each command is (when that info is available, of course):

    #!/bin/bash
    
    commands=`compgen -c`
    let count=1
    
    for i in ${commands[@]}
    do
    
            what=`whatis $i`
    
            echo -e "n33[38;5;148m$count. $i: 33[39m"
            echo -e "$what"
    
            ((count++))
    
    
    done
    

    Last edited by Admin: pre tags added.

    • brbsix Feb 21, 2015 @ 13:11

      Curtis, FYI when you used commands=`compgen -c`, it loaded commands with a string (albeit a very long one). So in this instance, you could have used:

      for i in $commands
      

      The ${commands[@]} format is generally reserved for use with arrays. It worked in this instance but is not a good habit. If the output contained spaces the aforementioned would fail. You’d probably want to do this:

      Load output of compgen into an array named commands (the -t options strips trailing newline)

      readarray -t commands < <(compgen -c)
      

      Note the quotes to prevent word splitting. The for loop will then run through ${commands[0]}, ${commands[1]}, ${commands[2]}, etc…

      for i in "${commands[@]}"
      

      In my endless quest for Bash excellence, here is your script cleaned up a bit. It will ignore commands without any whatis output. For commands with multiple whatis entries, it will only display the first. Using $((++count)) allows for increment and output at the same time.

      while IFS= read command; do
          what=$(whatis $command 2>/dev/null | head -n1 | awk -F'- ' '{print $2}')
          [[ -n $what ]] && echo "[$((++count))] $command - $what"
      done < <(compgen -c | sort)
      
  • Rajkumar.M Jul 19, 2012 @ 12:31

    Excellent!!!…..

  • LinuxRawkstar Jul 19, 2012 @ 16:19

    GR8! Hidden gem. Lovin’ it.

  • Rajsekhar G Jul 19, 2012 @ 17:16

    Awesome bozz…… Thnx. :)

  • samspade Jul 20, 2012 @ 0:19

    LOL !

    whatis man
    man whatis

  • Ashok Jul 20, 2012 @ 7:21

    try “man man” :)

  • tintam Jul 22, 2012 @ 14:07

    Or if you’re in a gnu bash shell, pressing tab twice will list all available commands

  • Patrick Jul 25, 2012 @ 12:49

    Awesome!! never heard before! Thanks for the Tip

  • Ramon Nov 18, 2012 @ 4:19

    Thanks for sharing!! This will come in handy for sure.

  • Anonymous Jul 10, 2023 @ 8:31

    This is awesome, I leanred something new today. I love bash :)

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.