0

In my Linux machine I am able to find commands starting with ls by

$ ls<TAB-key>

I get the results like this,

ls           lsb_release  lscpu        lshw         lsipc        lslogins     lsmod        lsof         lspcmcia     lss16toppm   
lsattr       lsblk        lsdiff       lsinitramfs  lslocks      lsmem        lsns         lspci        lspgpot      lsusb   

Now like lsmod, I would like to know what else are the commands exists.

From $ man lsmod I get to know there are other commands like,

SEE ALSO
       insmod(8), modprobe(8), modinfo(8) depmod(8)

But from the terminal I couldn't find the commands with mod string by using Wild Cards. Please guide, how it can be done in any Unix & Linux distros

  • You don't mean apropos 'mod' or man -k 'mod' ? – Z0OM May 26 '23 at 20:10
  • I don't know if that is what you mean apropos -w '*mod*' | cut -d' ' -f1 | grep 'mod' or apropos -w '*mod*' | cut -d'(' -f1 | grep 'mod' or apropos -w '**' | cut -d'(' -f1 | grep 'mod' – Z0OM May 26 '23 at 20:21
  • 1
    man -k '' | cut -d'(' -f1 | grep 'mod' | Is that what you are looking for, the examples with apropos and man ? Let me know and I'll post it as an answer. – Z0OM May 26 '23 at 20:32
  • From my knowledge, as far as I know I cannot use wild cards to find commands. I just asked it in here on my curiosity. @BlockchainOffice I just tried the commands you've given, somehow I am not getting expected output. Thanks for letting me to know about the command apropos – Dev Anand Sadasivam May 26 '23 at 20:38
  • 3
    You didn't use any wildcards for ls or lsmod, so what's the significance of that example to this question? – muru May 26 '23 at 21:04
  • If you're asking why hitting TAB-TAB after typing mod doesn't suggest completions such as modinfo and modprobe then it's likely because these commands are in /usr/sbin, and /usr/sbin is not in your user's PATH – steeldriver May 26 '23 at 23:23

3 Answers3

1

A few shells have builtin support for that.

zsh

Many of the zsh shell's introspection builtin commands take a -m argument to do pattern matching. That's the case of whence (copied and extended from ksh) used to identify commands and the variants provided for convenient for other shell users (which same whence -c for csh users, type (standard), same as whence -v for SysV shell users) and the standard hash builtin to manipulate internal hash tables including that of paths of commands.

whence -m '*mod*'
  type -m '*mod*'
 which -m '*mod*'
  hash -m '*mod*'

The first 3 also look in builtins, functions, keyword, aliases; add -p to limit to commands in $PATH like for hash.

Or you can look for matching executable files in $PATH (mapped to the $path array) manually with¹:

print -rC1 -- $^path/*mod*(DN-*)

In addition to some builtin commands, for introspection (and for helping with completion), zsh exposes some of its internal state and cached data in some special variables. For instance the hash table of commands and their path is exposed in the $commands special associative array, so you can look in its keys with for instance:

print -rC1 -- ${(kM)commands:#*mod*}

Where the pattern matching is done using the ${(M)array:#pattern} operator.

There, you can also configure completion system to attempt wildcard matching in addition to normal completion. For instance, at a minimum, with:

zstyle ':completion:*' completer _complete _match
autoload -Uz compinit
compinit

In your ~/.zshrc, typing

$ *mod*<Tab>

Will show you a list of possible commands matching that patterns. While:

$ man -s1,8 *mod*<Tab>
Completing manual page
check-module                  mk_modmap
chmod                         modinfo
combine_lang_model            modprobe
depmod                        perlmod
dh_gtkmodules                 perlmodinstall
[...]

Will show you a list of pages in section 1 (user commands) and 8 (system management commands) of the manual that contain mod.

When starting zsh for the first time, you should be shown a newuser menu to tune all this. The above can be found in:

(1)  Continue to the main menu.
[...]
(2)  Configure the new completion system.  (Recommended.)
[...]
(2)  Run the configuration tool (compinstall)
[...]
1.  Completers:  choose completion behaviour for tasks such as
    approximation, spell-checking, expansion.
[...]
m.     Set completers that modify the behaviour of the four main ones above.
[...]
1.     _ignored: Use patterns that were previously ignored if no matches so far.
2.     _list:    Only list matches until the second time you hit TAB.
3.     _oldlist: Keep matches generated by special completion functions.
4. (*) _match:   If completion fails, retry with pattern matching.
5.     _prefix:  If completion fails, retry ignoring the part after the cursor.

And select 4 above. But I would strongly recommend going through all the menus as there are many more goodies in there.

bash

In the bash shell, you can use:

compgen -cX '!*mod*'

Same as:

compgen -A command -X '!*mod*'

compgen -c / compgen -A command give a list of known commands (including keywords, aliases, builtins and functions), -X is to exclude those matching a pattern, but with that pattern starting with !, that's changed from exclusion to inclusion.

rc and derivatives

In rc, where the $path list is tied to the $PATH environment variable like in csh or zsh,

ls -d -- $path/*mod* >[2] /dev/null

Note that rc doesn't have the equivalent of zsh's D or -* glob qualifiers, so that list is not restricted to files that are executable and doesn't include hidden files.

rc shares a misfeature with the Bourne shell and most of its derivatives, that non-matching glob patterns are left as-is, so if there's no match in a given directory, we'd get a literal /that/dir/*mod*. We work around that by passing the list to ls which complains about those non-existing files with * in their name but discard those errors with >[2] /dev/null (same as the 2> /dev/null of Bourne-like shells or fish)

fish

Similar to rc, with the same caveat regarding non-executable, but with hidden file support added by prefixing {.,} to the pattern:

printf '%s\n' $PATH/{,.}*mod*

POSIX sh

In POSIX sh, you could define a function such as:

find_commands() (
  pattern=$1
  IFS=:; set -o noglob
  set -- $PATH''
  IFS=; set +o noglob
  for dir do
    for file in "${dir:+$dir/}"$pattern "${dir:+$dir/}".$pattern; do
      if [ -f "$file" ] && [ -x "$file" ]; then
        printf '%s\n' "$file"
      fi
    done
  done
)

Used as:

find_command '*mod*'

¹ Note that it doesn't work properly if there are empty $PATH components as in PATH=/bin/:/usr/bin: where the last empty component means looking in the current working directory. That could be worked around by using ${^path/#%/.} to replace those empty strings with ., but in any case, having empty $PATH components (or $PATH components being relative paths in general) is very bad practice from a security and reliability standpoint and shouldn't be done. Same applies to solutions for other shells given below that manually look in $PATH/$path directories.

0

To search man pages, you can use apropos (same as man -k with many man implementations), which does some regexp matching on an index of all man pages and their summary.

With the apropos from mandb (as commonly found on Linux-based systems),

apropos mod

Will returns the entries for the man pages whose either name or summary matches that mod regular expression (note that's different from shell glob wildcard pattern), that is where it contains mod.

You can also specify a section or list of sections to look into.

To look for mod in the name only and not summary, you can use the fact that page names hardly ever contain spaces while their summary almost always does.

So:

apropos -s1,8 '^[^ ]*mod[^ ]*$'

Should return the man pages in sections 1 and 8 whose name contains mod, as that regular expression matches on the start of the subject (^) followed by any number (*) of characters other than space ([^ ]) followed by mod, followed by any number (*) of characters other than space ([^ ]) followed by the end of the subject ($), so in short mod without any space around it.

0
# in at least bash
start cmd:> ( IFS=: ; find $PATH -type f -name 'ls*' -perm /111 -ls )
    96723      4 lrwxrwxrwx   1 root     root            4 Mär 19 23:08 /usr/bin/lsmod -> kmod
   281915      4 lrwxrwxrwx   1 root     root           11 Mär 19 22:35 /usr/bin/lsb-release -> lsb_release
   733984      4 -rwxr-xr-x   1 root     root         2479 Mär 20 05:53 /usr/bin/lss16toppm
   734097      4 -rwxr-xr-x   1 root     root         1821 Mär 19 22:36 /usr/bin/lsdev
   955869     12 -rwxr-xr-x   1 root     root        10514 Mär 19 22:35 /usr/bin/lsb_release
  1070923     16 -rwxr-xr-x   1 root     root        14215 Mär 20 00:13 /usr/bin/lsusb.py
  1245610    136 -rwxr-xr-x   1 root     root       138016 Apr  1 19:45 /usr/bin/ls
  1254310    104 -rwxr-xr-x   1 root     root       104632 Apr  1 21:16 /usr/bin/lscpu
  1254311     76 -rwxr-xr-x   1 root     root        73928 Apr  1 21:16 /usr/bin/lsfd
  1254312     52 -rwxr-xr-x   1 root     root        51384 Apr  1 21:16 /usr/bin/lsipc
  1254313     28 -rwxr-xr-x   1 root     root        26808 Apr  1 21:16 /usr/bin/lsirq
  1254314     32 -rwxr-xr-x   1 root     root        31304 Apr  1 21:16 /usr/bin/lslocks
  1254315     40 -rwxr-xr-x   1 root     root        39096 Apr  1 21:16 /usr/bin/lsmem
  1254316     40 -rwxr-xr-x   1 root     root        39096 Apr  1 21:16 /usr/bin/lsns
  1254878    136 -rwxr-xr-x   1 root     root       137400 Apr  1 21:22 /usr/bin/lsblk
  1254879     52 -rwxr-xr-x   1 root     root        51384 Apr  1 21:22 /usr/bin/lslogins
  1255279     84 -rwxr-xr-x   1 root     root        85136 Mär 19 22:34 /usr/bin/lsscsi
  1255280    176 -rwxr-xr-x   1 root     root       179912 Mär 19 22:50 /usr/bin/lsof
  1258862   2980 -rwxr-xr-x   1 root     root      3048800 Mär 20 06:13 /usr/bin/lsar
  1264433     16 -rwxr-xr-x   1 root     root        14456 Mär 19 22:35 /usr/bin/lsattr
  1264457     12 -rwxr-xr-x   1 root     root        11989 Mär 20 04:18 /usr/bin/lsinitrd
  1271261    104 -rwxr-xr-x   1 root     root       106376 Mär 19 23:14 /usr/bin/lspci
  1272752    252 -rwxr-xr-x   1 root     root       256328 Mär 20 00:13 /usr/bin/lsusb
Hauke Laging
  • 90,279