The hint presents a way to generate a list of all of the Unix commands in your execution PATH (see this Unix FAQ for an explanation of the execution PATH variable) with a one-line synopsis for each program (assuming this one-line description is available). This is accomplished via a rather complicated pipeline of commands:
Here are the first several lines of output from the above command when run on my Mac:
SystemStarter - Start, stop, and restart system services
Xmark - summarize x11perf results
Xnest - a nested X server
Xquartz - X window system server for Quartz operating system
Xvfb - virtual framebuffer X server for X Version 11
a2p - Awk to Perl translator
...
If you want the output of the above command to be saved into a file instead of appearing in the Terminal window, add a greater-than sign and then the name of the file you want to create at the end of the command.For example, if you want to save the output into a file named unix_commands.txt in your Documents folder, add
> ~/Documents/unix_commands.txt
at the end of the above command:
If you just want to use the above command to get the list of commands with descriptions, that's all you need to know. The rest of this hint will explain how the above command works by dissecting it into its various parts.
A pipeline of Unix commands is a series of commands separated by the pipe symbol (a vertical bar: |). The output of each command is used as input for the next command in the sequence. The first part of the above command is:
echo $PATH
This outputs the colon-separated list of directories (folders) that are in your execution PATH. The next stage of the command pipes this output into:
sed -e 's/:/ /g'
which changes each colon (:) into a space. The next stage of the pipeline pipes the resulting space-separated list of directories into the find command via the xargs command:
xargs -J % find % -maxdepth 1 ( -type f -or -type l )
The -J % option to the xargs command tells it to substitute the strings it receives as input at the place designated by % in the subsequent (find) command. This means that we are starting the search of the find command from the list of directories that we got from the PATH variable. For each directory in the PATH, we find all files or symbolic links (-type f -or -type l) that are in that directory. (The -maxdepth 1 tells it not to look in sub-directories.) We need to use the xargs command here because the find command expects to get the list of directories as command-line arguments, not as input.
One important note: we are making the simplifying assumption that none of the directories in the PATH have spaces in their names. That is usual for Unix directories.
The output from the find command will be a list of the files that are in the directories in the PATH. Each entry in this list will be a full pathname -- i.e. it will include the names of the directories where the file is. (e.g. one entry in this list will be /usr/bin/cmp). The next stage of the pipeline pipes this list of file pathnames into the basename command via the xargs command:
xargs basename
This gets rid of the directory information and just leaves us with a list of filenames (e.g. cmp instead of /usr/bin/cmp). We then pipe this list of files into the sort command, followed by the uniq command. This sorts the list of files into alphabetic order and eliminates any duplicates. And then we pipe that list of files into the whatis command via the xargs command:
sort | uniq | xargs whatis
The output from the whatis command is a series of lines (of descriptive info about the commands) from the (previously generated) whatis database. Some of these lines describe functions and other items that happen to be named the same as the commands we are interested in. There might be some irrelevant errors from the whatis command, so we discard any error messages by redirecting the standard-error stream (#2) to /dev/null:
2> /dev/null
The info we are interested in comes mostly from section 1 of the man pages (section 1 describes Unix commands, sections 2 and 3 describe functions useful to programmers, etc), but some commands are listed in section 1m or section 6, and several are in section 8, and so we pipe the results into the grep command to filter out only those lines that refer to the sections we are interested in:
grep -E '((1|1m|6|8))'
This also gets rid of the lines relating to commands for which whatis has no description. (This means that our final result won't be a complete list of all commands in the PATH, but will only show those commands for which a one-line description is available.)
The last stage in our pipeline is the following Perl command which removes the now-useless references to section 1 from the lines and reformats the lines for easy readability:
This first extracts the command name and description into separate Perl variables ($name, $descrip) and then gets rid of all occurrences of the man page section numbers from the command names. It then prints each command name in a field of width 20 (so that the subsequent descriptions all line up nicely) followed by a dash and then the description.
If you want to understand the stages of this pipeline better, you could remove the stages one by one starting from the right side, running the command each time to see what the output is.
[robg adds: Sorry for the use of the div blocks for the code, as I know they're not universally liked. However, in this case, it was the best way to present the long, complex string such that it could be easily copied and pasted.]

