1

Which command could I use list all commands that start with the letter g?

I have read the question here but I seek for an answer without arbitrary limits. If shell completion gives an answer, it should be included.

However, if there is an answer which runs in many/most shells that would be preferable.

Would:

( set -f; find ${PATH//:/ } -type f -maxdepth 1 -executable )

be a suitable answer? Not all finds have all those options, correct?

1 Answers1

0

The find command that you show,

( set -f; find ${PATH//:/ } -type f -maxdepth 1 -executable )

would be suitable for most circumstances, given that it was run on a machine with GNU find installed, which implements both -maxdepth and -executable (and I really don't want to try to craft an equivalent test for -executable using standard find predicates). It also requires bash for doing the parameter substitution on the value of PATH, changing each : into a space (this could also be done through setting IFS=: and using the variable unquoted as is, removing the requirement for bash).

In another answer to a similar question, I also I protected the find command from interpreting the search paths as potential options with --. The command shown here is using the approach with IFS, and is also slightly tweaked after doing some proper testing of it:

(
    set -f; IFS=:
    find -L -- $PATH -maxdepth 1 ! -type d -executable
) 

The ! -type d ensures that executable symbolic links, but not directories, are also found. The -L option makes sure that meta data relating to found symbolic links are taken from the thing that the link is pointing to (this prevents finding symbolic links to accessible, i.e. executable, subdirectories).

Testing this against compgen -c in bash shows that compgen -c will produce a list of commands overlapping with the result from the above find command, and that any additional commands that compgen -c finds is limited to built-in commands that have no external implementation.

Obviously, to limit this to commands starting with the character g, you would also want to use -name 'g*' (compgen -c g in bash).

A shell that provides tab completion of commands, like bash, may expose commands for interacting with this mechanism. These commands will unlikely be portable between shells, and possibly not even between versions of the same shell. The find command above, seems to provide a fairly good approximation to what a tab completion of external commands would give you though, and only relies on the presence af GNU find.

For a rewrite of the -executable predicate using standard find predicates, see Stéphane Chazelas' answer to another question (which deals with -readable, but the solution is analogous to -executable).

The -maxdepth predicate is also non-standard, but are more commonly implemented across various variations of the find command.

Kusalananda
  • 333,661