3

Do you have any easy idea to define some alias in .bashrc for finding some command that you want to search (when you forgot its name) in your machine, visiting all "bin" directories, maybe using regex?

e.g.

ls /bin /sbin /usr/bin | grep program

Do you have any idea how to use regex for searching all bin directories?

1
  • Did I misunderstand, and you aren't searching for regex or names, you don't remember exactly? Mar 13, 2012 at 5:00

9 Answers 9

4

you can use whereis to find all binaries matching the name you are searching for

> whereis -b ls
ls: /bin/ls

-b option is for binaries only, without it you will find sources and man page files as well

> whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz
3

Use the bash function type. It's better than whereis because it will identify functions built into bash and aliases as well as binary executables. whereis is better because it will do some pattern matching -- type only find the thing you specify.

Use the -a option to show all occurrences of the executable in your path.

~$ type python
python is /usr/local/bin/python
~$ type -a python
python is /usr/local/bin/python
python is /usr/bin/python
python is /usr/local/bin/python
~$ whereis -b python
python: /usr/bin/python /usr/bin/python2.4 /usr/lib/python2.4 /usr/local/bin/python /usr/local/bin/python2.6 /usr/local/bin/python2.5 /usr/local/bin/python2.7 /usr/local/bin/python2.7-config /usr/local/bin/python2.5-config /usr/local/bin/python2.6-config /usr/local/lib/python2.6 /usr/local/lib/python2.5 /usr/local/lib/python2.7 /usr/include/python2.4

~$ whereis -b time
time: /usr/bin/time /usr/include/time.h
~$ type -a time
time is a shell keyword
time is /usr/bin/time
1
  • This was the best answer for me. I need to store a program's path to a variable and I did that with following: PATH='type -p ffmpeg' (replace single quotes with backtics). Thank you, Doug harris. I hope my example helps others, too :)
    – ipruthi
    May 3, 2014 at 6:17
3

This one works with no external dependencies (only shell builtins) and will work with busybox ash as well.

Sometimes you cant remember how to spell it exactly though, for those of us who just need to find a close match, there is this function to add to the bashrc:

find_bin(){
for x in ${PATH//://*${1}* }*${1}*; do
    [ -f "$x" ] && echo $x
done
}

find_bin grep will list all of the binaries in $PATH with grep in the name along with their path {grep, egrep, fgrep, bugreport,... }

this can accept the following syntax:

  • a*z - with az
  • a?z - with a<1 character>z
  • a[0-9]z - with az
  • a[a-z]z - with az
  • a[A-Z]z - with az
  • a*{a,z}*z - with a .... same as a[az]z

if you occasionally want it to only match the whole word and not report egrep, fgrep or bugreport when you type grep, you can remove the asterisks and add them back at the command line only where you want them

find_bin(){
for x in ${PATH//://${1} }${1}; do
    [ -f "$x" ] && echo $x
done
}

for this one extra syntax is needed for matching the beginnings and endings

  • *grep - will match commands ending in gre (will find grep,egrep and fgrep, but not bugreport)
  • grep - will only match exact string grep
  • grep* - will match commands beginning with grep
  • all patterns above apply as well
3
  • find_bin "[aeiou]b.*" does not find ''ubuntu-bug'' or ''ebrowse''. Your script uses globbing, not regexes, afaik, but I don't really understand ` ${PATH//://*${1}* }*${1}*` Mar 14, 2012 at 10:20
  • The op said "maybe using regex". for file names globbing is good enough 99% of the time. Other solutions require tools that may not be available to the shell - for instance, my box doesn't have whereis, while this uses built-ins that will work on nearly all shells - though I should add type $1 to see if it is an alias or function in a bashrc. ${PATH//://*${1}* }*${1}* is substring manipulation, it replaces the ':'s in PATH with a "*[the first arg]*space" the last one is needed because there is no colon on the end, thus grokking it into something for ... in ... can use. Mar 14, 2012 at 13:00
  • +1 for the explanation. Now I understand the expression. Mar 14, 2012 at 15:13
2

You can use man -k to search inside the manpage of each command:

man -k packet


PF_PACKET (7)        - packet interface on device level.
gpgsplit (1)         - Split an OpenPGP message into packets
ip6tables (8)        - IPv6 packet filter administration
iptables (8)         - administration tool for IPv4 packet filtering and NAT
lft (1)              - print the route packets trace to network host
lft.db (1)           - print the route packets trace to network host
packet (7)           - packet interface on device level.
pcap-filter (7)      - packet filter syntax
tc-bfifo (8)         - Packet limited First In, First Out queue
tc-pfifo (8)         - Packet limited First In, First Out queue
tcptraceroute (1)    - A traceroute implementation using TCP packets
tcptraceroute.db (8) - print the route packets trace to network host
tcptraceroute.mt (1) - A traceroute implementation using TCP packets
traceproto (1)       - print the route packets trace to network host
traceproto.db (1)    - print the route packets trace to network host
traceroute (1)       - print the route packets trace to network host
traceroute-nanog (1) - print the route packets trace to network host
traceroute.db (1)    - print the route packets trace to network host
traceroute6 (1)      - print the route packets trace to network host
traceroute6.db (1)   - print the route packets trace to network host


man -k "packet limited"
tc-bfifo (8)         - Packet limited First In, First Out queue
tc-pfifo (8)         - Packet limited First In, First Out queue

The numbers inside parenthesis represents the section of the man page of the command, section 3 and 5 for example are not for commands. Of course you have to consider that sadly some commands do not have a man page.

1

which does exactly that:

which commandname
1
  • Apart from the regex part, to search for not completly known names. Mar 13, 2012 at 4:59
1
apropos program/library/related/anything really

Searches the man pages for your serchword, regex support included. I can never remember how to spell ncmpcpp, so by

apropos mpd

ing I can find everything mpd, including ncmpcpp

0

To put it into your .bashrc, an alias isn't useful because aliases don't take parameters, but a function will do:

pfind () {
  for d in ${PATH//:/ }
  do
    find $d -regex $d/"$1"
  done
}

pfind '.*[ou]b.*h'

find ... -reges searches for regular expressions for the whole path, so we need to repeat $d.

pfind shall stand for program-find (or PATH find).

2
  • In case you have a directory with spaces, a safer way to iterate is: IFS=:; for dir in $PATH; do ...; done. Also, instead of parsing ls, just use globbing directory: echo *"$1"* (not regular expressions though. Mar 12, 2012 at 23:43
  • echo $d/* in above command would output all entries of the directory, if one file matches - independent from regexes or not. Normally, I advocate against using ls, so I tried it here too - and find is a fine solution (you normally don't have directories below ~/bin, else add an -maxdepth 1 to the find params after the path. Mar 13, 2012 at 4:57
0

In bash, if you remember the first character or two of a command, type <character><character><TAB><TAB> to see the list of all commands whose name starts with <character><character>.

In Linux, "locate string" will list all files and directories with "string" as part of its name. (You'd need to have built its DB first, with updatedb. On CentOS, a cron.daily job runs updatedb.) This won't tell you which one might be executable; it's just another way to find more info.

0

Assuming you have a mlocate package:

locate programname

You must log in to answer this question.