Thursday, September 23, 2010

The Bash Shell

The shell is the traditional interface used by UNIX and GNU/Linux. In contrast to the X Window
System it is an interface that works with commands. In the beginning this can be a bit awkward, but the shell is very powerful. Even in these days the shell is almost unavoidable. The default shell on Slackware Linux is Bash. Bash means “Bourne-Again SHell”, which is a pun on the name of one of the traditional UNIX shells, the “Bourne Shell”. Slackware Linux also provides some other shells, but Bash is the main topic of this chapter.


Starting the shell
The procedure for starting the shell depends on whether you use a graphical or text-mode login. If you are logging on in text-mode the shell is immediately started after entering the (correct) password. If you are using a graphical login manager like gdm, log on as you would normally, and look in your window manager or desktop environment menu for an entry named “XTerm”. XTerm is a terminal emulator, after the terminal emulator is started the shell comes up. The shell might remind some people of MS-DOS. Be happy, it has nothing to do with DOS, the only similarity is that you can enter commands ;).


Executing commands
The most important job for the shell is to execute your commands. Let’s look at a simple example. Most UNIX variants have a command named whoami, which shows as which user you are logged in. Try typing whoami, and press the <enter> after that. The <enter> tells the shell that it should execute the command that you have typed on the current line. The output looks like this:

   hendro@laptop:-$ whoami
   hendro
   hendro@laptop:-$

As you can see the control is handed back to the shell after the command is finished.

Browsing through shell commands

It often happens that you have to execute commands that you executed earlier. Fortunately, you do not have to type them all over again. You can browse through the history of executed commands with the up and down arrows. Besides that it is also possible to search for a command. Press <control> + <r> and start typing the command you want to execute. You will notice that bash will display the first match it can find. If this is not the match you were looking for you can continue typing the command (till it is unique and a match appears), or press <control> + <r> once more to get the next match. When you have found the command you were looking for, you can execute it by pressing <enter>.

Completion
Completion is one of the most useful functionalities of UNIX-like shells. Suppose that you have a directory with two files named websites and recipe. And suppose you want to cat the file websites (cat shows the contents of a file), by specifying websites as a parameter to cat. Normally you would type “cat websites”, and execute the command. Try typing “cat w”, and hit the <tab> key. Bash will automatically expand what you typed to “cat websites”. But what happens if you have files that start with the same letter? Suppose that you have the recipe1.txt and recipe2.txt files. Type “cat r” and hit <tab>, Bash will complete the filename as far as it can. It would leave you with “cat recipe”. Try hitting <tab> again, and Bash will show you a list of filenames that start with “recipe”, in this case both recipe files. At this point you have to help Bash by typing the next character of the file you need. Suppose you want to cat recipe2, you can push the <2> key. After that there are no problems completing the filename, and hitting <tab> completes the command to “cat recipe2.txt”. It is worth noting that completion also works with commands. Most GNU/Linux commands are
quite short, so it will not be of much use most of the time. It is a good idea to practice a bit with completion, it can save alot of keystrokes if you can handle completion well. You can make some empty files to practive with using the touch command. For example, to make a file named recipe3.txt, execute touch recipe3.txt.

Redirection
The shell allows you to take use of stdin and stdout using the “<” and “>”. Data is redirected in which way the sharp bracket points. In the following example we will redirect the md5 summaries calculated for a set of files to a file named md5sums:


$ md5sum * > md5sums
$ cat md5sums
6be249ef5cacb10014740f61793734a8 test1
220d2cc4d5d5fed2aa52f0f48da38ebe test2
631172a1cfca3c7cf9e8d0a16e6e8cfe test3


As we can see in the cat output the output of the md5sum * output was redirected to the md5sums file.
We can also use redirection to provide input to a command:
$ md5sum < test1
6be249ef5cacb10014740f61793734a8 -
This feeds the contents of the test1 to md5sum.

Pipes
You can also connect the input and output of commands using so-called pipes. A pipe between
commands can be made with the “|” character. Two or more combined commands are called a
pipeline.

The “syntax” of a pipe is: command1 | command2 ... | commandn. If you know how the most basic
UNIX-like commands work you can now let these commands work together. Let’s look at a quick
example:
$ cat /usr/share/dict/american-english | grep "aba" | wc -l
123


The first command, cat, reads the dictionary file /usr/share/dict/american-english. The
output of the cat command is piped to grep, which prints out all files containing the phrase “aba”. In
turn, the output of “grep” is piped to wc -l, which counts the number of lines it receives from stdin.
Finally, when the stream is finished wc prints the number of lines it counted. So, combined three
commands to count the number of words containing the phrase “aba” in this particular dictionary.
There are hundreds of small utilities that handle specific tasks. As you can imagine, together these
commands provide a very powerful toolbox by making combinations using pipes.

No comments:

Post a Comment