Bashing Linux
First there was the Bourne shell, then the C shell, then the Korn shell, the Z shell, and now the Bourne Again Shell! This is usually the standard command shell that gets installed on Linux systems, so I thought it appropriate to talk about it a little.
The command line is what scares the bejeezus out of most new Unix users. Somehow it seems that the single little command prompt and blinking cursor has the rap of being the most user-hostile development since the Inquisition (and not much newer). Yet, now that I'm comfortable with the shell, a GUI-only interface scares me more because you can only do something for which a widget has been configured to do. Would you expect someone to make a button handy for the following:
find ${1:=$HOME} -size +${2:=1000}k -depth -printf '%k\t%p\n'
| sort -nr | less
Too bad, because this little gem will find all files in a specified directory (the default is your home directory) that are larger than a size you dictate (the default is 1MB). This little command will find those large space-eating files that make your freespace go away. If you like, however, you can run it from a button or a menu or whathaveyou. I run it from a script called ``fbig'' for ``find big space-eating files I should know about''. One time I found an 80MB log file that procmail was creating in a tucked away little directory, writing verbose log info about every piece of mail I get every hour. Whew! So that's how come my /home partition was filling up so often! With a little reading and practice, you too can become a command line commando with BASH!
You and Your .bashrc
There's a little file in your home directory you may have not discovered yet: .bashrc. When you get a moment, take a look at it with a pager like less or more. You'll probably see mention of a place for ``user-specific functions, variables, and variables.'' These are the essence of how you make your shell into a home.
Variables are substitutions your shell will automatically make for your convenience. If you type uls=/usr/local/src in your .bashrc file, when you type cd $uls at the command line, you'll instantly be transported to the /usr/local/src directory, and with a lot fewer keystrokes.
Aliases are lots of fun too. Let's say you get tired of typing ``source /.bashrc'' all the time (because you've really gotten into customizing your environment), so you decide to write an alias for it: ``alias sbr='source /.bashrc' ''. If you spend a day updating your configuration file, and you source it perhaps 50 times (you busy beaver, you!) you could save 650 keystrokes! Your hands will hurt less and you can hold more doughnuts and Doritos.
Functions are like little scripts that you build right into your shell environment. You could make that ``fbig'' command into an alias or function. You could probably build it into a function that was much more elaborate, or you could build a small but handy function like this:
his()
{
history ${1:-22}
}
This little function simply lists the last 22 lines of history (your last 22 commands) or lets you specify a range of commands. So instead of typing ``history 22'' you just type ``his'' and you get the same thing. You could write a spiffier function like the following:
tarc()
{
tar czvf $1.tar.gz $2
}
You could do the same thing for ``tar tvfz'' or ``tar xvfz'' which could let you view a tar file or extract it. Of course, my favorite is ``tarm'' for ``tar move directory tree.'' Sometimes you fill up a filesystem and want to move an entire directory tree to another filesystem to make more room. To do this at the command line would be something like
cd source-directory
tar xvf -)
This could work nicely as a function too:
tarm()
{
source=$1
dest=$2
cd $source
tar cf - . | (cd $dest; tar xvf -)
}
Tokens and Spaghetti-O's
If you've followed everything I've written until now, you probably don't need this article at all! I have to jump into things quickly because I don't have space to explain very much in this little column. But you've probably wondered what the $1 and the . and - are all about. There are lots of little doodads like this in Unix, and perhaps I can talk a little bit about some of them.
First, $1 and $2 are the first two arguments of a command that BASH
recognizes. For example, if you typed cp foo bar, you're
telling bash to copy the first argument (a file named foo) to a file
by the name of the second argument, bar. The variables $1 and $2
are very handy because BASH can remember them and reuse them in
various way, as you can begin to see in the examples above. The
possibilities of what you can do with functions, variables, and
aliases are quite limitless when you put your mind to it.
Second, ``.'' and ``-'' have to do with standard input and standard
output. (Actually, ``.'' is a BASH built-in command that says to read
a file and execute its contents in the current shell.) Standard input
is what you type at the screen or where you tell a program to get its
input. Standard output is what the program spits back at you.
Standard error is the program's way of spitting up on you.
``|'' is a way of ``piping'' standard output from one program
and directing it into the standard input of another program. With the
``tarm'' function we tar up everything in one directory and pipe it to
standard output, which feeds the standard input of a child process
spawned by the shell tar was first running in. How about that, family
values for Unix!?
Well, I can barely scratch the surface of this topic in a single column, but you can read more about it in a book by Newham and Rosenblatt called Learning the Bash Shell from O'Reilly and Associates. Another good book is Beginning Linux Programming from Wrox Publishing; its first few chapters get into many of these basic ideas.