Once upon a time, we talked a bit about man pages, and how useful they are for learning about a new program. We didn’t really get into how you find programs that you might want to run. This is what we’ll start exploring in the rest of this post.
First, a few things to know. Most executable files, also called “binaries” are
stored in a bin
directory. This is just convention, since technically a
binary file can live anywhere. There are generally a few bin
directories on
any given UNIX system. Some of them are:
/bin
- User utilities fundamental to both single and multi-user environments. These programs are statically compiled and therefore do not depend on any system libraries to run.
/sbin
- System programs and administration utilities fundamental to both single and multi-user environments. These programs are statically compiled and therefore do not depend on any system libraries to run.
/usr/bin
- Common utilities, programming tools, and applications.
/usr/sbin
- System daemons and utilities (executed by users).
/usr/local/bin
- Local executables, libraries, etc.
/usr/local/sbin
- Local executables, libraries, etc.1
But, there can be many more. A quick use of the find(1)
command (we talked
about find [last week][find]) can help me get a picture of how many there are on
my system:
$ find / -type d -name "bin"
find: /home/erica/.ssh: Permission denied
/usr/X11R6/bin
/usr/local/bin
/usr/bin
find: /usr/libexec/auth: Permission denied
find: /var/authpf: Permission denied
find: /var/backups: Permission denied
find: /var/cron/atjobs: Permission denied
find: /var/cron/tabs: Permission denied
find: /var/db/ldap: Permission denied
find: /var/db/yubikey: Permission denied
find: /var/games/hackdir/save: Permission denied
find: /var/nsd/etc: Permission denied
find: /var/nsd/run/xfr: Permission denied
find: /var/quotas: Permission denied
/var/spool/ftp/bin
find: /var/spool/ftp/bin: Permission denied
find: /var/spool/ftp/etc: Permission denied
find: /var/spool/ftp/hidden: Permission denied
find: /var/spool/smtpd: Permission denied
/var/www/bin
find: /var/www/cache: Permission denied
find: /var/sysmerge: Permission denied
/bin
find: /etc/iked/private: Permission denied
find: /etc/isakmpd/private: Permission denied
find: /etc/ldap/certs: Permission denied
find: /etc/skel/.ssh: Permission denied
find: /etc/ssl/private: Permission denied
find: /etc/ssl/acme/private: Permission denied
find: /etc/acme: Permission denied
find: /root: Permission denied
That’s a lot more output than I care about, so I can use two more tools we’ve
learned about previously to clean it up a bit. I’m going to use the pipe
operator |
to send the output of my find
command to the grep
command. I’m
also going to tell grep
to ignore (-v
) lines that match the pattern
“Permission Denied”:
$ find / -type d -name "bin" |grep -v "Permission denied"
find: /home/erica/.ssh: Permission denied
/usr/X11R6/bin
/usr/local/bin
/usr/bin
find: /usr/libexec/auth: Permission denied
find: /var/authpf: Permission denied
find: /var/backups: Permission denied
find: /var/cron/atjobs: Permission denied
find: /var/cron/tabs: Permission denied
find: /var/db/ldap: Permission denied
find: /var/db/yubikey: Permission denied
find: /var/games/hackdir/save: Permission denied
find: /var/nsd/etc: Permission denied
find: /var/nsd/run/xfr: Permission denied
find: /var/quotas: Permission denied
/var/spool/ftp/bin
find: /var/spool/ftp/bin: Permission denied
find: /var/spool/ftp/etc: Permission denied
find: /var/spool/ftp/hidden: Permission denied
find: /var/spool/smtpd: Permission denied
/var/www/bin
find: /var/www/cache: Permission denied
find: /var/sysmerge: Permission denied
/bin
find: /etc/iked/private: Permission denied
find: /etc/isakmpd/private: Permission denied
find: /etc/ldap/certs: Permission denied
find: /etc/skel/.ssh: Permission denied
find: /etc/ssl/private: Permission denied
find: /etc/ssl/acme/private: Permission denied
find: /etc/acme: Permission denied
find: /root: Permission denied
And, that did not work at all! The reason is the “Permission denied” message is
being output on what is knows as “standard error” while the rest of the messages
are being output on what is known as “standard output”. We’ll get into those in
a later post, for now we’ll just fix the issue by redirecting standard error to
standard output before piping it to grep
:
$ find / -type d -name "bin" 2>1 |grep -v "Permission Denied"
/usr/X11R6/bin
/usr/local/bin
/usr/bin
/var/spool/ftp/bin
/var/www/bin
/bin
Nice. Finally we have the output we were looking for.
This is one of the things that I love about the command line. It can be such a rich learning environment. You go in thinking you’re just going to write a quick post on how to find commands, and next thing you know you have 3 more things you need to explain before you can do that.
All that to say, that there could be many bin
dirs on your system, and there
are generally “binaries” or “programs” in those directories. It can be fun to
poke around in there and see what is available. You might find some gems. For
example, say I’m feeling very “elly” and want to see some commands that start
with the letter l:
$ cd /usr/bin
$ ls l*
lam ld less libnetcfg locale logger look lpr
last ldd lesskey libtool locate login lorder lprm
lastcomm leave lex lndir lock logname lpq ltrace
Voila! A bunch of programs that all start with the letter l, and all should have a man page I can read to learn more about. Sometimes when I’m bored, I just pick a random program from my system and read it’s man page.
Another good way to find programs that’s a bit less labour intensive is the
apropos
command, also known as man -k
. You just pass a keyword to the
apropos
command and it will return you a list of programs that are related to
that keyword. So, for example say I want to know about users, I could do:
$ man -k users
rusers(1) - who is logged in to machines on local network
users(1) - list current users
getusershell, endusershell, setusershell(3) - get legal user shells
npppd-users(5) - user database file
rpc.rusersd(8) - logged in users server
endusershell, setusershell, getusershell(3) - get legal user shells
crontab(1) - maintain crontab files for individual users
help(1) - help for new users and administrators
last(1) - indicate last logins of users, ttys, and hosts
mesg(1) - display (do not display) messages from other users
rwall(1) - send a message to users logged on a host
skeyaudit(1) - warn users if their S/Key will soon expire
w(1) - display users who are logged on and what they are doing
wall(1) - write a message to users
__thrsleep, __thrwakeup(2) - userspace thread sleep and wakeup
__thrwakeup, __thrsleep(2, 3) - userspace thread sleep and wakeup
Net::Netrc(3p) - OO interface to users netrc file
adduser, rmuser(8) - add and delete users from the system
rmuser, adduser(8) - add and delete users from the system
rpc.rwalld, rwalld(8) - write messages to users currently logged in server
rwalld, rpc.rwalld(8) - write messages to users currently logged in server
From there, you can read those man pages and find even more information, especially in the “See Also” section of the program’s man page. It’s not quite as fun as randomly clicking on Wikipedia links, but… a close second.
New Terms
- stderr
- Standard error. A magic place where errors can be sent. They will also echo on your screen.
- stdout
- Standard output. A magic place where output is sent. It also echo’s to your screen.
- apropos
- Equivalent to
man -k
but much more fun to type. A program for searching for man pages on a given topic.
-
http://man.openbsd.org/OpenBSD-current/man7/hier.7 [find]: /post/Finding-Files ↩︎