FreeBSD Tips and Tricks for 2005

By the time you read this, the 2004 holiday season will have dissolved into
memory. I spent the last days of the year going through my list of "things I
want to check out if I ever get the chance." As usual, I found some interesting
tidbits.

Beastie and Beerware

At least once a year, I like to comb through the files on my FreeBSD system
to see if there are any new docs, scripts, or manpages that I've missed. I
started my search in /usr/share/examples, and the first thing that
caught my eye was a subdirectory called BSD_daemon:

The README explains each of the files in this directory, created by
Poul-Henning Kamp and protected
by the Beerware license (also explained in the README).

The README also gives the instructions for creating a GIF and PNG
using the fig2dev utility. That utility wasn't on my system, but a
quick Google search indicated that it is part of the transfig suite of tools. I
quickly installed that package then ran the commands required to generate the
images:

Adding Interaction to Scripts

Earlier in the year I had experimented with dialog, which allows
you to add interactive menus to your shell scripts. At the time, I scoured the
Internet for some working examples but was disappointed. I could only find a
few that demonstrated creating a menubox, which is only one of
dialog's box options. While man dialog does a pretty
good job of explaining each option, I find it easier to have a working example
to refer to when I'm learning something new.

For your benefit, here are examples for each type of dialog box. These are
Bourne shell scripts, so you can easily read each script and use it as a
template for creating your own interactive scripts. To test each script, first
set them as executable:

# chmod +x [a-z]*

Notice that I used filename globbing with my chmod command. I
didn't want to set the README file as executable (+x),
but I wanted to match all of the other files in this directory. The files I
wanted to match all have lowercase names, and the [a-z] before the
* wildcard means to match all files with lowercase letters.

Also, because the scripts are in /usr/share/examples and that
directory isn't in the default path, you must give the full path to each script
in order to execute it. Alternately, you can cd into that
directory and put a ./ before the script's name, like this:

# cd /usr/share/examples
# ./yesno

In Case of Emergency

It's rare that things go wrong once you pass the initial learning phase,
where it seems that you're reinstalling your system from scratch every second
day. However, it's always good to be aware of the various emergency exits just
in case something does go wrong.

If you're running FreeBSD 5.2 or higher, check out man rescue,
then take a look through ls /rescue. It's reassuring to know there
is a safety net of utilities available in the unlikely event that you can't
access /bin or /sbin. The manpage also gives step-by-step
instructions on how to proceed in such an emergency. It's well worth printing
and storing with your offline documentation.

Have you ever really screwed up a configuration file, or worse, accidentally
deleted it from your system? If that file was in /etc, all isn't lost.
Your system should have copies of the originals safely tucked away in
/usr/share/examples/etc/.

Finally, the one place you don't want to be when you're playing with the
rm command is /dev. Have you ever noticed that a long
listing in this directory includes two extra fields not seen elsewhere on your
file system? For example, compare these two listings:

Instead of showing the size of the file in bytes, a long listing of a device
file shows the major number followed by the minor number. These numbers
represent the type of device so that the kernel knows how to interact with the
device. This means that if you were to accidentally delete /dev/fd0,
simply issuing the command touch /dev/fd0 wouldn't fix it. Instead,
use the mknod command, which uses this syntax:

# mknod fd0 c 4 10

The c indicates that this is a character device; note the
c was in the long listing as the first letter next to the
permissions set. What does all of this mean? If you accidentally delete a device,
you need to know three things in order to recreate it: whether it is a block or
character device, its major number, and its minor number. If you have another
FreeBSD system available, you can retrieve that information by doing a long
listing for the missing device. If you know you don't have access to another
system, consider backing up /dev or printing out a copy of ls -l
/dev.

Reading Material

I was pleasantly surprised by the increase in FreeBSD articles this past
year. Many of these are available in /usr/share/doc/en/articles.

Hack #89 of BSD Hacks
demonstrates how to update your offline documentation with newly posted
articles. Ensure that this line is in your CVS supfile:

doc-all tag=.

Because the sources are SGML, you'll need this port to convert them to
HTML:

Some of the articles are ideal for new users, and, even if you're not a new
user, they are well worth pointing out to your novice friends. In
/usr/share/doc/en/articles, check out new-users and
freebsd-questions. For those who feel at a loss when asked to explain
what FreeBSD is, see explaining-bsd. If you have a hankering to
contribute to the project but feel you can't because you don't write code, read
through contributing.

Have you ever wanted a visual map of how the BSDs integrate into the Unix
family tree? Take a look at more /usr/share/misc/bsd-family-tree.
Perhaps you've had a hankering to create a manpage. You'll find templates
called man.template and mdoc.template in
/usr/share/misc. Even better, /usr/share/examples/mdoc
contains the formatting for three well-commented sample manpages.

A GUI rc.conf

Whenever I can, I like to take a long perusal through the ports collection
while installing and trying out interesting sounding ports on my test system. I
had been meaning to try out thefish for a
while. I started by installing the package:

# pkg_add -r thefish

However, when I ran thefish, it ran the ncurses version. You
know that blue screen you see when you type /stand/sysinstall,
where your mouse doesn't work and you have to use your arrow and tab keys to
navigate? That type of screen uses the ncurses library to provide
a quasi-GUI at a console. This is great on a system that doesn't have X
installed. However, if you're using a GUI and want a nice-looking menu, you
should instead use the widget set appropriate to your windowing
environment.

What do I mean? Once I uninstalled the console-only binary of
thefish, I built the port instead:

# cd /usr/ports/sysutils/thefish
# make install clean

It presented me with this menu:

[ ] CONSOLE Disable X11 support
[x] GTK Use GTK+ for the X11 interface
[ ] QT Use Qt for the X11 interface

GTK+ and QT are the possible widget sets. A widget set controls how a window
looks; for example, where the minimize and maximize controls are, and how they
look. If you use the Gnome desktop, you're using the GTK+ widget set. If you
use KDE, you're using QT. I prefer the look of QT windows, so I built my
version of thefish with QT. If you take a closer look at the
screenshots at the web site for thefish, you'll see that the
buttons on the QT menu are different from the second (unlabeled) screenshot
which represents the GTK+ version of the program.

Once you have thefish, you have an easy-to-use interface for
changing /etc/rc.conf parameters with brief descriptions regarding
each parameter. You also have the ability to add other parameters if you've
installed an application that comes with its own rc.conf knobs.

Changing Your Mind

Have you ever built a port, seen its menu of options, and then changed your
mind? For example, after building the QT version of thefish, I had
the urge to uninstall it to try the GTK+ version. However, when I issued my
make command, it didn't present the options menu. I instead
noticed a one-liner stating that my configuration had been saved, followed by
make happily recreating the QT version.

RSS

I have a list of web sites that I visit on a daily basis to keep up with
news, weather, articles, and blogs. I was aware of RSS, but up to now hadn't had
the time to check out the various RSS clients. A search through the ports
collection showed a dozen or so clients, each of which I tried. I wanted an
attractive GUI interface that was easy to configure. In my book,
/usr/ports/www/akregator is the clear winner.

Some of the other RSS clients came with pre-defined lists. While it was
convenient to pick out some of the more common sites, such as Slashdot and
FreeBSDDiary, often the URLs were outdated and I still had to go to the web site
and hunt for the proper RSS URL.

Out of the clients, akregator was the
easiest to use to add a feed. Most other clients don't check the URL until you try to
download a feed; if there is a typo, or you don't specify the full path to the
RSS feed, this step will fail.

With akregator, I can type slashdot.org and it
will connect to Slashdot, locate the feed, and correctly save the URL as
http://slashdot.org/index.rss. This worked for all of the sites I
tried, making it pretty goof-proof.

On a side note, I also use firefox, which supports adding RSS
feeds as live
bookmarks. That link gives screenshots and explains the basics of RSS and
how to use live bookmarks. It also hyperlinks to del.icio.us, a site you don't
want to visit unless you have some spare time to kill. While it's convenient to
have RSS feeds integrated into the browser, I prefer akregator's
interface.

Now that I've joined the RSS generation, I don't know how I lived without
it. I'm informed whenever a new blog/article is posted, the weather has changed
(hey, I don't always remember to look outside), or a port has been added or
modified.

For example, I found out about /usr/ports/sysutils/pkg_rmleaves
from the Freshports feed
approximately eight minutes after its commit. Having used
/usr/ports/sysutils/pkg_cutleaves in the past to prune unwanted ports,
I was intrigued.

Because the port was just committed, I ran cvsup to grab the
sources in order to build the port. When I ran pkg_rmleaves, it
presented me with a checklist dialog menu where I could easily
pick and choose which ports to uninstall. This port offers a very convenient
way to manage orphaned (and possibly no longer required) ports.

Conclusion

I hope you also have opportunities to poke about and learn more about your
FreeBSD system. Have you come across anything interesting that you haven't seen
discussed before? If so, post a comment describing your find so other readers
can benefit from it.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.