Cover | Table of Contents | Colophon
http://opensource.org) Unix operating systems
are an interesting breed. They like to poke under the surface of
things, to find out how things work, and to figure out new and
interesting ways of accomplishing common computing tasks. In short,
they like to "hack."bash is not the
default shell on a BSD system, for either the superuser or regular
user accounts.tcsh
shell is also brimming with shortcuts and
little tricks designed to let you breeze through even the most
tedious of tasks. Spend a few moments learning these tricks and
you'll feel right at home. If
you're new to the command line or consider yourself
a terrible typist, read on. Unix might be a whole lot easier than you
think.http://opensource.org) Unix operating systems
are an interesting breed. They like to poke under the surface of
things, to find out how things work, and to figure out new and
interesting ways of accomplishing common computing tasks. In short,
they like to "hack."bash is not the
default shell on a BSD system, for either the superuser or regular
user accounts.tcsh
shell is also brimming with shortcuts and
little tricks designed to let you breeze through even the most
tedious of tasks. Spend a few moments learning these tricks and
you'll feel right at home. If
you're new to the command line or consider yourself
a terrible typist, read on. Unix might be a whole lot easier than you
think.tcsh, but often its simpler variant,
csh, which doesn't support all of
the tricks provided in this hack.tcsh
package in their respective package collections.tcsh uses the up and down arrow keys to scroll
through your command history. If there is a golden rule to computing,
it should be: "You should never have to type a
command more than once." When you need to repeat a
command, simply press your up arrow until you find the desired
command. Then, press Enter and think of all the keystrokes you just
saved yourself. If your fingers fly faster than your eyes can read
and you whiz past the right command, simply use the down arrow to go
in the other direction.tcsh
prompt displays %
when you're logged in as a regular user and
hostname# when you're logged in
as the superuser. That's a fairly useful way to
figure out who you're logged in as, but we can do
much better than that.dru@~:grep prompt ~/.cshrc
if ($?prompt) then
set prompt = "%B%n@%~%b: "
tcsh
prompt, as I've been using my favorite customized
prompt for the past few years. The possible prompt formatting
sequences are easy to understand if you have a list of possibilities
in front of you. That list is buried deeply within man
cshrc, so here's a quick way to zero in on
it:dru@~:man cshrc /prompt may include
/ to invoke
the
manpage search utility. The search string
prompt may include brings you to the right
section, and is intuitive enough that even my rusty old brain can
remember it.set prompt = "%B%n@%~%b: "
|
Character
|
Explanation
|
|---|---|
|
"
|
Starts the prompt string. |
bindkey command,
which is built into the tcsh shell. As the name
suggests, this command binds certain actions to certain keys. To see
your current mappings, simply type bindkey. The
output is several pages long, so I've included only
a short sample. However, you'll recognize some of
these shortcuts from
[Hack #1]
.Standard key bindings "^A" -> beginning-of-line "^B" -> backward-char "^E" -> end-of-line "^F" -> forward-char "^L" -> clear-screen "^N" -> down-history "^P" -> up-history "^U" -> kill-whole-line Arrow key bindings down -> history-search-forward up -> history-search-backward left -> backward-char right -> forward-char home -> beginning-of-line end -> end-of-line
^ means hold down your Ctrl key. For example,
press Ctrl and then l, and you'll
clear your screen more quickly than by typing
clear. Notice that it doesn't
matter if you use the uppercase or lowercase letter.complete-word-fwd. Before I do the actual
binding, I'll first check which keys are available:dru@~:bindkey | grep undefined
"^G" -> is undefined
"\305" -> is undefined
"\307" -> is undefined
<snip>
tcsh shell that
is capable of understanding bindings. Your FreeBSD terminal provides
the kbdcontrol command to map commands to your
keyboard. Unfortunately, neither NetBSD nor OpenBSD offer this
feature. You can, however, remap your keyboard under X, as described
later.kbdcontrol is as follows:kbdcontrol -f number "command"
|
Number
|
Key combination
|
|---|---|
|
1, 2, . . . 12
|
F1, F2, . . . F12
|
|
13, 14, . . . 24
|
Shift+F1, Shift+F2, . . . Shift+F12
|
|
25, 26, . . . 36
|
Ctrl+F1, Ctrl+F2, . . . Ctrl+F12
|
|
37, 38, . . . 48
|
Shift+Ctrl+F1, Shift+Ctrl+F2, . . . Shift+Ctrl+F12
|
|
49
|
Home
|
|
50
|
Up arrow
|
|
51
|
Page Up
|
|
52
|
Numpad - (Num Lock off)
|
moused may already be
enabled. The job of this daemon is to listen for mouse data in order
to pass it to your console driver.moused is most likely started for you when you
boot up. You can check with this:% grep moused /etc/rc.conf
moused_port="/dev/psm0"
moused_type="auto"
moused_enable="YES"
moused needs to know three things:auto)moused_flags="-m 2=3"
http://www.thinkgeek.net/ to stock up on cube
goodies and caffeine. Or, you could take advantage of some of the
entertainments built into your operating system.login: dru
Password:
Last login: Thu Nov 27 10:10:16 on ttyv7
"You can't have everything. Where would you put it?"
-- Steven Wright
/stand/sysinstall. Choose
Configure, then Distributions,
and select games with your spacebar. Press Tab to
select OK, then exit out of
sysinstall when it is finished.% grep fortune ~/.cshrc
/usr/games/fortune
% echo '/usr/games/fortune' >> ~/.cshrc
source shell command, which re-executes the
contents of the file. This can come in handy if
you've updated an alias and want to take advantage
of it immediately:% source ~/.cshrc
Indifference will be the downfall of mankind, but who cares?
% echo '/usr/games/fortune' > ~/.logout
lock (and it's
available for NetBSD and OpenBSD). Its default invocation is simple:% lock Key: 1234 Again: 1234 lock /dev/ttyv6 on genisis. timeout in 15 minutes. time now is Fri Jan 2 12:45:02 EST 2004 Key:
lock will request that the
user input a key which will be used to unlock the terminal. This is a
good thing, as it gives the user an opportunity to use something
other than her login password. If the user tries to be smart and
presses Enter (for an empty password), the lock
program will abort.Key: lock: type in the unlock key. timeout in 10:59 minutes
-n switch. If the system is a
personal workstation, % echo $PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/
local/bin:/usr/X11R6/bin:/home/dru/bin
dru's home directory. However, it
won't look for executables placed directly in my
home directory, or /home/dru. Since
bin isn't created by default, I
should do that first:% cd % mkdir bin
#!/bin/sh # a comment explaining what the script does the command to be executed
# character. It's surprising how
forgetful you can be six months down the road, especially if you
create a lot of scripts. For this reason, you should also give the
script a name that reminds you of what it does.% ls -l /usr/share/skel
total 24
drwxr-xr-x 2 root wheel 512 Jul 28 16:09 ./
drwxr-xr-x 27 root wheel 512 Jul 28 16:06 ../
-rw-r--r-- 1 root wheel 921 Jul 28 16:09 dot.cshrc
-rw-r--r-- 1 root wheel 248 Jul 28 16:09 dot.login
-rw-r--r-- 1 root wheel 158 Jul 28 16:09 dot.login_conf
-rw------- 1 root wheel 371 Jul 28 16:09 dot.mail_aliases
-rw-r--r-- 1 root wheel 331 Jul 28 16:09 dot.mailrc
-rw-r--r-- 1 root wheel 797 Jul 28 16:09 dot.profile
-rw------- 1 root wheel 276 Jul 28 16:09 dot.rhosts
-rw-r--r-- 1 root wheel 975 Jul 28 16:09 dot.shrc
dot. However,
when the files are copied into a user's home
directory, the dots turn into literal dots
(.). Also, the files in this directory are owned
by root, but when a new user is created, the
copied over files will change ownership as they are placed in that
user's home directory.unison is a tool for maintaining synchronized
copies of
directories. I've used
it to maintain a central repository of all of my dot files, shell
scripts, signatures file, SpamAssassin configuration—basically
any file I'd like to have available, regardless of
which host I happen to be logged into.unison from the NetBSD pkgsrc
collection:# cd /usr/pkgsrc/net/unison # make install clean
unison web site for
details.unison. Then, I create a
directory to receive the files I've stored in the
/usr/work/sync directory at
host.example.com. I call the local directory
~/sync.% unison ~/sync ssh://username@host.example.com://usr/work/sync
p = /home/david/.unison; bn = .unison
Contacting server...
p = /home/david/sync; bn = sync
username@host.example.com's password:
script command which,
not surprisingly, allows you to script your session. This command is
extremely simple to use. Simply type script:% script
Script started, output file is typescript
script will create an output file
named typescript in your current directory. If
you prefer, you can specify a more descriptive name for your script
file:% script configure.firewall.nov.11.2003
Script started, output file is configure.firewall.nov.11.2003
Script done, output file is configure.firewall.nov.11.2003
-a (append) switch:% script -a configure.firewall.nov.11.2003
script extremely useful, especially when
I'm learning how to configure something for the
first time. I can easily create a written record of which commands I
used, which commands were successful, and which commands caused which
error messages. It also comes in handy when I need to send an error
message to a mailing list or a program's maintainer.
I can simply copy or attach my script file into an email.find, grep,
sed, tr, or
mount make you shudder? If not, remember that you
still have novice users who are intimidated by—and therefore
aren't gaining the full potential of—these
commands.man find wasn't all that
enlightening.w's: which,
whereis, and whatis.
(Personally, I'd like to see some
why and when commands, but
that's another story.)which to find the path to a program. Suppose
you've just installed xmms and
wonder where it went:% which xmms
/usr/X11R6/bin/xmms
% echo `which xmms` >> somefile
find, grep,
sed, tr, or
mount make you shudder? If not, remember that you
still have novice users who are intimidated by—and therefore
aren't gaining the full potential of—these
commands.man find wasn't all that
enlightening.w's: which,
whereis, and whatis.
(Personally, I'd like to see some
why and when commands, but
that's another story.)which to find the path to a program. Suppose
you've just installed xmms and
wonder where it went:% which xmms
/usr/X11R6/bin/xmms
% echo `which xmms` >> somefile
`), often found on the
far left of the keyboard on the same key as the tilde
(~). If you instead use the
single quote (') character, usually
located on the right side of the keyboard on the same key as the
double quote ("), your file will contain the
echoed string which xmms instead of the desired
path.which's switches work. Here is an
example from the C shell:% which -a xmms -a: Command not found. /usr/X11R6/bin/xmms % which which which: shell built-in command.
which the user is using.
Here, the user used the which which is built into
the C shell and doesn't support the options used by
the which utility. Where then is that
which? Try the whereis command:% whereis -b which
which: /usr/bin/whichgrep command does just that,
searching inside files and reporting on those that contain a given
piece of text.$USER. Try this:% grep -s '$USER' *
add-user:if [ "$USER" != "root" ]; then
bu-user: echo " [-u user] - override $USER as the user to backup"
bu-user:if [ "$user" = "" ]; then user="$USER"; fi
del-user:if [ "$USER" != "root" ]; then
mount-host:mounted=$(df | grep "$ALM_AFP_MOUNT/$USER")
.....
mount-user: echo " [-u user] - override $USER as the user to backup"
mount-user:if [ "$user" = "" ]; then user="$USER"; fi
grep has searched through all
files in the current directory, displaying each line that contained
the text $USER. Use single quotes around the text
to prevent the shell from interpreting special characters. The
-s option suppresses error messages when
grep encounters a directory.$USER. Use the -l option
to create that list for you:% grep -ls '$USER' *
add-user
bu-user
del-user
mount-host
mount-user
% grep -sc '$USER' * | grep -v ':0' | sort -k 2 -t : -r
mount-host:6
mount-user:2
bu-user:2
del-user:1
add-user:1
-c flag lists each
file with a count of matching lines, but it unfortunately includes
files with zero matches. To counter this, I piped the output from
grep into a second grep, this
time searching for ':0' and using a second option,
grep
will do the job:% grep -v '^$' letter1.txt > tmp ; mv tmp letter1.txt
^$ anchors to both the start and the
end of a line with no intervening characters—the regexp
definition of a blank line. The -v option reverses
the search, printing all nonblank lines, which are then written to a
temporary file, and the temporary file is moved back to the original.grep must never output to the same file it is
reading, or the file will end up empty.sed as:% sed '/^$/d' letter1.txt > tmp ; mv tmp letter1.txt
/^$/d' is actually a sed
script. sed's normal mode of
operation is to read each line of input, process it according to the
script, and then write the processed line to standard output. In this
example, the expression '/^$/ is a regular
expression matching a blank line, and the trailing
d' is a sed function that
deletes the line. Blank lines are deleted and all other lines are
printed. Again, the results are redirected to a temporary file, which
is then copied back to the original file.sed
can also do the
work of grep:% sed -n '/$USER/p' *
% grep '$USER' *
-n (no-print, perhaps) option prevents
sed from outputting each line. The pattern
/$USER/ matches lines containing
$USER, and the p function
prints matched lines to standard output, overriding
-n.sed
command scare you off. sed is a powerful utility
capable of handling most of your formatting needs. For example, have
you ever needed to add or remove comments from a source file? Perhaps
you need to shuffle some text from one section to another.tr and
col.sed
allows you to specify an address range
using a pattern, so let's put this to use. Suppose
we want to comment out a block of text in a source file by adding
// to the start of each line we wish to comment
out. We might use a text editor to mark the block with
bc-start and bc-end:% cat source.c
if (tTd(27, 1))
sm_dprintf("%s (%s, %s) aliased to %s\n",
a->q_paddr, a->q_host, a->q_user, p);
bc-start
if (bitset(EF_VRFYONLY, e->e_flags))
{
a->q_state = QS_VERIFIED;
return;
}
bc-end
message("aliased to %s", shortenstring(p, MAXSHORTSTR));
sed script such as:% sed '/bc-start/,/bc-end/s/^/\/\//' source.c
if (tTd(27, 1))
sm_dprintf("%s (%s, %s) aliased to %s\n",
a->q_paddr, a->q_host, a->q_user, p);
//bc-start
// if (bitset(EF_VRFYONLY, e->e_flags))
// {
// a->q_state = QS_VERIFIED;
// return;
// }
//bc-end
message("aliased to %s", shortenstring(p, MAXSHORTSTR));
// to
the start of all lines (s/^/\/\//) that lie
between the two markers (/bc-start/,/bc-end/).
This will apply to every block in the file between the marker pairs.
Note that in the sed script, the
/ character has to be escaped as
\/ so it is not mistaken for a delimiter.1, meaning
"nontext". We'll
declare the variable tswitch and define it as
tswitch =
1.delim with
a space as the delimiter, so delim = ' '.new_delim = '\t'.mount command, only to discover that you
didn't even have the right to use the floppy drive
in the first place!mount command before you can access the contents
of that floppy. While this may seem strange at first, it actually
gives Unix more flexibility. An administrator can mount and unmount
filesystems as they are needed. Note that I used the word
administrator. Regular users
don't have this ability, by default.
We'll change that shortly.mount different filesystems. In Windows, a floppy
will always contain the FAT12 filesystem. BSD understands
floppies formatted with either FAT12 or
UFS, the Unix File System. As you
might expect from the name, the UFS filesystem is assumed unless you
specify otherwise.mount_smbfs and
smbutil utilities to
mount Windows shares and view or access resources on a Microsoft
network. However, both of those utilities have a caveat: they require
an SMB server. The assumption is that somewhere
in your network there is at least one NT or 2000 Server.# cd /usr/ports/net/sharity-light # make install clean
\\
NetBIOSname
\
sharename.
It starts with double backslashes, then contains the
NetBIOS name of the computer to access
and the name of the share on that computer.periodic scripts.% ls /etc/periodic/daily | grep clean
100.clean-disks
110.clean-tmps
120.clean-preserve
130.clean-msgs
140.clean-rwho
150.clean-hoststat