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.

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