Linux command to list all available commands and aliases
Asked Answered
D

18

340

Is there a Linux command that will list all available commands and aliases for this terminal session?

As if you typed 'a' and pressed tab, but for every letter of the alphabet. Or running 'alias' but also returning commands.

Why? I'd like to run the following and see if a command is available:

ListAllCommands | grep searchstr
Davie answered 4/6, 2009 at 0:29 Comment(2)
press TAB button twice to list all commands available with environmentBullington
See also this answer on compgen.Marxmarxian
L
693

You can use the bash(1) built-in compgen

  • compgen -c will list all the commands you could run.
  • compgen -a will list all the aliases you could run.
  • compgen -b will list all the built-ins you could run.
  • compgen -k will list all the keywords you could run.
  • compgen -A function will list all the functions you could run.
  • compgen -A function -abck will list all the above in one go.

Check the man page for other completions you can generate.

To directly answer your question:

compgen -ac | grep searchstr

should do what you want.

Lying answered 4/6, 2009 at 7:7 Comment(10)
Is there an equivalent to this for csh/tcsh? Those terminals also have some sort of autocompleting function used on tab, so maybe something exists?Pact
Instead of compgen | grep, it can be more efficient to pass the string as argument to compgen itself (if it's known to be a prefix, as implied in the question). In this case, that would be compgen -ac searchstr.Circuit
Actually, ubuntu shows 'nothing appropiate' on whatis compgen and 'No manual entry' for man compgen.Miletus
@MarAvFe: That's because it is a bash built-in, not a separate command with its own man page. You'll need to read the bash(1) man page, or run help compgen at a bash command line.Lying
By extension, doing compgen -c | sort | uniq | less will print all commands available without duplicated lines and sorted alphabetically.Devilish
comspec -c command shows also functions and keywords, I want only commands.Sturrock
compgen /system/bin/sh: compgen: inaccessible or not found the command that lists commands is not in the list of commandsGillam
@Gillam It's a bash built-in. sh won't have it (assuming bourne - I have no idea what /system/bin/sh is - that's a rather non-standard path)Lying
@Lying I'm on AndroidGillam
Hi, where does compgen take all these commands, built-ins, aliases, etc.. etc... ? Are they stored in a file?Rogelioroger
B
45

Add to .bashrc

function ListAllCommands
{
    echo -n $PATH | xargs -d : -I {} find {} -maxdepth 1 \
        -executable -type f -printf '%P\n' | sort -u
}

If you also want aliases, then:

function ListAllCommands
{
    COMMANDS=`echo -n $PATH | xargs -d : -I {} find {} -maxdepth 1 \
        -executable -type f -printf '%P\n'`
    ALIASES=`alias | cut -d '=' -f 1`
    echo "$COMMANDS"$'\n'"$ALIASES" | sort -u
}
Bow answered 4/6, 2009 at 1:12 Comment(11)
This is very close but it's not including aliases. How can I append alias | cut -f1 to the results but before the sort?Davie
Why bother sorting if the only purpose is to put the output through grep anyway? Unix philosophy is to make simple tools and then chain them together if required, so leave sort out of ListAllCommands and if the user wants the output sorted they can do that.Vest
The sort is to remove duplicates.Bow
find -executable doesn't work for me. Was that option renamed?Blackburn
@fotomut Maybe you are using Mac OS? On a Mac, you can instead run: find . -type f -exec sh -c 'test -x {} && echo {}' \; That worked for me when recursively searching for executable files in the current folder.Abscind
@VictorZamanian I'm ssh into a unix box actually. But vault answer works for me on my unix and my mac too.Blackburn
You can also use -perm -111.Kerwinn
This does not find commands that are symlinks to executables. Use the option -L on to follow symlinks to their destination. Note: -L is an option and not part of the matching expression, as such it has to be placed before the path on the command line. In this case find -L {}Erfert
Might want to redirect STDERR to /dev/null to suppress nonexistent directory warnings. echo -n $PATH | xargs -d : -I {} find {} -maxdepth 1 -executable -type f -printf '%P\n' 2> /dev/null | sort -u (+1 for zsh compatibility)Protoplast
I not have understand nothing of this syntaxSturrock
what is the uppercase "%P" in "printf"? On internet I have found File's name with the name of the command line argument under which it was found removed. but there are no examples and I did not understand what this explanation means.Sturrock
K
32

There is the

type -a mycommand

command which lists all aliases and commands in $PATH where mycommand is used. Can be used to check if the command exists in several variants. Other than that... There's probably some script around that parses $PATH and all aliases, but don't know about any such script.

Kannry answered 4/6, 2009 at 0:36 Comment(3)
Even if it is not an answer to the question I think it is a better solution to the problem then the call to grep. So you can do type -a foo and if foo isn't available it returns command not found or something like that. So you are able to check for a command without calling the command itself.Unrestrained
Actually it is an answer to the question, as the OP asked "I'd like to run the following and see if a command is available", so the purpose is to see if a command is available and this answer clearly works.Tay
@lothar, what if the command you're looking for is, uh, what was it, "startserver"?, "serverstart"?, "server-something-or-other"?. I know, I'll just "grep -i" for server and see if it's there. Oops. Bzzz, not with this solution. matey :-) I'm not going to vote this answer down (since it's useful even if in a limited way) but a full blown solution would take into account that grep is for regular expressions, not just fixed strings.Tort
R
20

The others command didn't work for me on embedded systems, because they require bash or a more complete version of xargs (busybox was limited).

The following commands should work on any Unix-like system.

List by folder :

ls $(echo $PATH | tr ':' ' ')

List all commands by name

ls $(echo $PATH | tr ':' ' ') | grep -v '/' | grep . | sort
Romanic answered 7/9, 2017 at 9:11 Comment(2)
This still relies on tr. Why not simply ls $(echo ${PATH//:/ })?Juliajulian
This is what I wanted. Simple and evidentBattleax
D
6

Use "which searchstr". Returns either the path of the binary or the alias setup if it's an alias

Edit: If you're looking for a list of aliases, you can use:

alias -p | cut -d= -f1 | cut -d' ' -f2

Add that in to whichever PATH searching answer you like. Assumes you're using bash..

Decontaminate answered 4/6, 2009 at 0:42 Comment(0)
I
6

Alternatively, you can get a convenient list of commands coupled with quick descriptions (as long as the command has a man page, which most do):

apropos -s 1 ''

-s 1 returns only "section 1" manpages which are entries for executable programs.

'' is a search for anything. (If you use an asterisk, on my system, bash throws in a search for all the files and folders in your current working directory.)

Then you just grep it like you want.

apropos -s 1 '' | grep xdg

yields:

xdg-desktop-icon (1) - command line tool for (un)installing icons to the desktop
xdg-desktop-menu (1) - command line tool for (un)installing desktop menu items
xdg-email (1)        - command line tool for sending mail using the user's preferred e-mail composer
xdg-icon-resource (1) - command line tool for (un)installing icon resources
xdg-mime (1)         - command line tool for querying information about file type handling and adding descriptions for new file types
xdg-open (1)         - opens a file or URL in the user's preferred application
xdg-screensaver (1)  - command line tool for controlling the screensaver
xdg-settings (1)     - get various settings from the desktop environment
xdg-user-dir (1)     - Find an XDG user dir
xdg-user-dirs-update (1) - Update XDG user dir configuration

The results don't appear to be sorted, so if you're looking for a long list, you can throw a | sort | into the middle, and then pipe that to a pager like less/more/most. ala:

apropos -s 1 '' | sort | grep zip | less

Which returns a sorted list of all commands that have "zip" in their name or their short description, and pumps that the "less" pager. (You could also replace "less" with $PAGER and use the default pager.)

Interrogatory answered 11/9, 2017 at 7:59 Comment(0)
I
5

Try this script:

#!/bin/bash
echo $PATH  | tr : '\n' | 
while read e; do 
    for i in $e/*; do
        if [[ -x "$i" && -f "$i" ]]; then     
            echo $i
        fi
    done
done
Impatiens answered 4/6, 2009 at 0:53 Comment(1)
This is the only code solution so far that does it for all commands, not just to see if a given known command exists. +1.Tort
A
4

For Mac users (find doesn't have -executable and xargs doesn't have -d):

echo $PATH | tr ':' '\n' | xargs -I {} find {} -maxdepth 1 -type f -perm '++x'
Acetaldehyde answered 24/10, 2012 at 15:41 Comment(2)
Thanks for this. I am actually using a non-mac unix where @AntsAasma answer didn't work. This works for me on mac and my unix too. What command can I type to determine the unix version I am on, so I can reply here to help other's with my issue?Blackburn
Linux <corporate_proprietary_build_info_here> Mon Dec 12 13:34:16 EST 2011 x86_64 x86_64 x86_64 GNU/LinuxBlackburn
B
3

Try to press ALT-? (alt and question mark at the same time). Give it a second or two to build the list. It should work in bash.

Ballad answered 4/6, 2009 at 0:50 Comment(2)
Or try hitting Esc at the start of a blank line four times.Valorize
That's amazingly useful, and I didn't already know it thanks :-)Effloresce
S
3

Here's a solution that gives you a list of all executables and aliases. It's also portable to systems without xargs -d (e.g. Mac OS X), and properly handles paths with spaces in them.

#!/bin/bash
(echo -n $PATH | tr : '\0' | xargs -0 -n 1 ls; alias | sed 's/alias \([^=]*\)=.*/\1/') | sort -u | grep "$@"

Usage: myscript.sh [grep-options] pattern, e.g. to find all commands that begin with ls, case-insensitive, do:

myscript -i ^ls
Schmo answered 4/6, 2009 at 1:50 Comment(0)
Y
3

It's useful to list the commands based on the keywords associated with the command.

Use: man -k "your keyword"

feel free to combine with:| grep "another word"

for example, to find a text editor: man -k editor | grep text

Yearn answered 7/11, 2014 at 17:46 Comment(0)
B
2

shortcut method to list out all commands. Open terminal and press two times "tab" button. Thats show all commands in terminal

Beamy answered 25/9, 2016 at 19:24 Comment(1)
And you pipe that into grep exactly how?Circuit
S
1

it depends, by that I mean it depends on what shell you are using. here are the constraints I see:

  1. must run in the same process as your shell, to catch aliases and functions and variables that would effect the commands you can find, think PATH or EDITOR although EDITOR might be out of scope. You can have unexported variables that can effect things.
  2. it is shell specific or your going off into the kernel, /proc/pid/enviorn and friends do not have enough information

I use ZSH so here is a zsh answer, it does the following 3 things:

  1. dumps path
  2. dumps alias names
  3. dumps functions that are in the env
  4. sorts them

here it is:

feed_me() {
    (alias | cut -f1 -d= ; hash -f; hash -v | cut -f 1 -d= ; typeset +f) | sort
}

If you use zsh this should do it.

Sidneysidoma answered 4/6, 2009 at 0:29 Comment(0)
P
0

The problem is that the tab-completion is searching your path, but all commands are not in your path.

To find the commands in your path using bash you could do something like :

for x in `echo $PATH | cut -d":" -f1`; do ls $x; done
Purlin answered 4/6, 2009 at 0:42 Comment(1)
It only shows all commands in the first directory of $PATHExcrescence
C
0

Here's a function you can put in your bashrc file:

function command-search
{
   oldIFS=${IFS}
   IFS=":"

   for p in ${PATH}
   do
      ls $p | grep $1
   done

   export IFS=${oldIFS}
}

Example usage:

$ command-search gnome
gnome-audio-profiles-properties*
gnome-eject@
gnome-keyring*
gnome-keyring-daemon*
gnome-mount*
gnome-open*
gnome-sound-recorder*
gnome-text-editor@
gnome-umount@
gnome-volume-control*
polkit-gnome-authorization*
vim.gnome*
$

FYI: IFS is a variable that bash uses to split strings.

Certainly there could be some better ways to do this.

Conglutinate answered 4/6, 2009 at 0:58 Comment(0)
K
-1

maybe i'm misunderstanding but what if you press Escape until you got the Display All X possibilities ?

Karilla answered 4/6, 2009 at 1:2 Comment(0)
T
-2
compgen -c > list.txt && wc list.txt
Tourist answered 5/4, 2015 at 0:5 Comment(2)
Consider adding a brief description of what this does or how this is supposed to work. At the very least, specify a reference link (usually the relevant man page) for following-up and understanding the proposed solution.Spirograph
Using a file is not always a good option. If you do need to, then at least make it a tmp file (if security not an issue.) compgen -c > /tmp/list.txt && /tmp/wc list.txtOconnor
H
-6

in debian: ls /bin/ | grep "whatImSearchingFor"

Hyperparathyroidism answered 4/6, 2009 at 0:37 Comment(1)
executables exist in all the directories in $PATH, not just /bin.Hare

© 2022 - 2024 — McMap. All rights reserved.