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.
bash
shell specifically, then my answer to that question covers that. Note that tab completion is not a standard feature and even though most shells implement it, the hooks (commands) that the shell provides to manipulate it will be different. Narrowing the question down to a particular shell would therefore be helpful. – Kusalananda Dec 16 '19 at 16:08