Department of Computer Science
Bash Tutorial


 
Preface

The goal of this tutorial is to give the beginner a very basic familiarity with bash, the standard UNIX shell of our department.  It is not comprehensive.   Covering only a small subset of commands and features, this should be considered a starting point.  Potential CS majors should pursue more knowledge of their computing and editing environments, assured that the cost of such learning will be more than compensated by time saved over the course of their years as a major.

Imagine not knowing how to cut and paste.  Imagine the tedium of deleting a section of a paper character by character.  Then imagine the tedium of retyping the section character by character in a different location.  Cut and paste are simple to learn, and save the user much time and effort.  Having a good command of one's computing/editing environment will aid one considerably as a programmer as well.

In this tutorial, we focus on the shell, where one interacts with the computer through textual commands.  While the drag, drop, and double-click of window-based interfaces to operating systems are sufficient for most users, a text-based interface offers surprising power to the serious user.
 
In the beginning...

If you're doing this tutorial as a class exercise, be sure to try everything shown for yourself.  Don't merely read it - do it!  There are instructions at the end of this tutorial for how to submit evidence of your work.  Plan to do this tutorial in one sitting so that all of your work is shown.

Let's assume you've just logged in for your first time.  After entering your name and password (uppercase/lowercase matters!), choose GNOME as your preferred desktop. You are initially faced with a number of windows (tutorial, registration, file manager).  Ignore these for now.  You never actually need use these windows and can close them if you wise.  To close a window, double click on the upper left box (with a minus) along the title bar of the window.

To work with the shell, you need to start a terminal window. In the upper-left corner, click the "Applications" menu, from which you should select the submenu "System Tools", then "Terminal".  Close the terminal window by double-clicking the upper left box along the title bar.  (You can also close the window by typing Control-D at the command line.  Now open another terminal window.  Repeat this a couple times until you're comfortable with it and have the process memorized.

Now onto the shell!  The terminal window is fairly empty to start with.  You'll likely see only a prompt, the beginning of what is called the command line.  For instance, on the machine "gbcs1" your prompt might look like:

gbcs1:~$

If you're in Glatfelter 112, your machine name will have the form "gbcs##". The prompt serves to (1) give you information about your current situation, and (2) indicate that the shell is awaiting your next command.  In this case, the text before the ":" is the name of your machine or host.  The text between the ":" and "$" is your current working directory.  A directory is what folders represent in window-based interfaces to operating systems.  Just as you can have files and folders in a folder, you can have files and directories in a directory.  The directory name "~" is shorthand for "home directory", the place where you store your files on this system.  After the "$" is the place where you type your next command.

The first thing you'll probably want to do is change your password.  Type the command "yppasswd", enter your current password one, and your new password twice.  You will not be able to see the passwords as you type them.  The first 6 characters of the password must contain at least two alphabetic characters and at least one numeric or special character.  Write this new password down and don't forget it!

gbcs1:~$ yppasswd
yppasswd:  Changing password for nuyuzr01
Enter login(NIS) password:
New password:
Re-enter new password:
NIS yppasswd/attributes changed on turing
gbcs1:~$

Now imagine you are up late programming one evening (inconceivable!) and take a break.  Upon returning to the computer room, you forget exactly which terminal you were working at, but there is a terminal window open to allow you to check to see if it's yours.  Type the command "whoami" (all one word) and press the Return key:

gbcs1:~$ whoami
nuyuzr01
gbcs1:~$

Oh good.  It is your terminal and you're in your home directory.  Hmm.  What time is it?  Enter the command "date".

gbcs1:~$ date
Thu Feb 30 23:11:04 EST 2009
gbcs1:~$

Dang it's late!  Should have started the assignment sooner (smirk).  There's an itching curiousity in the back of your mind that meshes nicely with the desire to procrastinate: "I know I'm in my home directory, but where exactly is that?".  The command "pwd" (print working directory) will tell you.

gbcs1:~$ pwd
/Accounts/turing/students/s12/nuyuzr01
gbcs1:~$

"whoami", "date", and "pwd" are simple commands.  There are many more commands and some can be very complex.   You'll remember the ones you use the most, but don't try or expect to remember every command you encounter.  It's more important to (1) know what commands are available, and (2) know where to find documentation for commands.  The command "man" is short for "manual" and will give you information about commands.  Enter "man pwd" to see the documentation of the command "pwd".

gbcs1:~$ man pwd
Reformatting page.  Wait... done

User Commands                                              pwd(1)

NAME
     pwd - return working directory name

SYNOPSIS
     /usr/bin/pwd

DESCRIPTION
     pwd writes an absolute path  name  of  the  current  working
     directory to standard output.
...

If such man pages are difficult to understand, there are a variety of other sources of information about UNIX systems similar to this.  Check out the helpful links at the Department of Computer Science Account Resource Page. There, you can find quick references, more tutorials, and more documentation than you could ever want.  In using "man", you can press space to page forward, "b" to page back, and "q" to quit.

The bash command line makes it simple to re-execute previous commands.  Bash keeps a command history and allows you to easily select and edit commands from this history.  Enter "history" to see the commands you've executed so far.

gbcs1:~$ history
   1  yppasswd
   2  whoami
   3  date
   4  pwd
   5  man pwd
   6  history
gbcs1:~$

There are a variety of ways to access previous commands.  The simplest is to use the up and down arrows to move through previous commands until you find the one you're interested in.  Use the up and down arrows to review your command history and press Return when you find the "date" command.  Then look at your history again.  Remember that you don't have to type "history" out again.  Two up arrows and a return will suffice.  Alternate between execution of the commands "date" and "history" using the arrow keys and return only until you're comfortable with using this feature.

Most commands you type will contain more information that these.  What do you do if you find you typed the first character wrong only after you'd completed the last?  Command line editing is easy with bash.  You can use the left and right arrow to move the cursor and edit your command.  Type "hooami" and press return.

gbcs1:~$ hooami
bash: hooami: command not found
gbcs1:~$

Now retrieve the previous command and edit it so that it correctly shows "whoami" and press Return.  Your cursor does not have to be at the end of the line to press Return.  There are many other tricks to editing the command line.  Bash uses "emacs-style" command line editing, so you are encouraged to learn how to use emacs editing commands and see which ones are applicable to bash command line editing as well.

Most commands have options which allow a single command to have many possible behaviors.  We will illustrate this with the command "ls" which lists the contents of the current working directory.  First, type "ls".  "public_html" is the name of the directory where you can put web pages.  If you do not have a "public_html" directory, create one now with the "mkdir" (make directory) command: 

gbcs1:~$ mkdir public_html
gbcs1:~$

An HTML file "~/public_html/index.html" for user nuyuzr01 will have the web address "http://cs.gettysburg.edu/~nuyuzr01/index.html".  When using "ls", a name ending with "/" indicates that it is the name of a subdirectory of the current directory.

gbcs1:~$ ls
public_html/

However, there's more in your home directory than meets the eye.  Files that start with "." are hidden files.  You can list all these files using the ls option "-a".  Enter the command "ls -a" to see these files (your files will vary).

gbcs1:~$ ls -a
./              .bash_history   .dt/            .mailrc*
../             .bash_logout*   .dtprofile*     .plan*
.Xauthority     .bash_profile*  .emacs*         .solregis/
.Xdefaults*     .bashrc*        .jetadmin/      public_html/

Now suppose you want to find out a lot more information about these files (e.g. size, date created, security info, etc.).  The option "-l" gives the long version of the directory listing.  Try it by adding the additional option "-a" onto the previous command as follows:

gbcs1:~$ ls -a -l
total 20
drwxr-xr-x   6 nuyuzr01      512 Jan 11 16:56 ./
drwxr-xr-x  22 root          512 Jan 11 15:45 ../
-rw-------   1 nuyuzr01      202 Jan 11 15:54 .Xauthority
-rwxr-xr-x   1 nuyuzr01       59 Jan 11 15:27 .Xdefaults*
-rw-------   1 nuyuzr01       54 Jan 11 15:37 .bash_history
-rwxr-xr-x   1 nuyuzr01      384 Jan 11 15:27 .bash_logout*
-rwxr-xr-x   1 nuyuzr01      404 Jan 11 15:27 .bash_profile*
-rwxr-xr-x   1 nuyuzr01      386 Jan 11 15:27 .bashrc*
drwxr-xr-x  11 nuyuzr01      512 Jan 11 15:38 .dt/
-rwxr-xr-x   1 nuyuzr01     5111 Jan 11 15:31 .dtprofile*
-rwxr-xr-x   1 nuyuzr01      351 Jan 11 15:27 .emacs*
drwxr-xr-x   2 nuyuzr01      512 Jan 11 16:58 .jetadmin/
-rwxr-xr-x   1 nuyuzr01       19 Jan 11 15:27 .mailrc*
-rwxr-xr-x   1 nuyuzr01      257 Jan 11 15:27 .plan*
drwx------   2 nuyuzr01      512 Jan 11 15:31 .solregis/
drwxr-xr-x   2 nuyuzr01      512 Jan 11 15:27 public_html/
gbcs1:~$ ls -al

There's actually a shorter way to enter this command: "ls -al" is equivalent.  Note that there are mysterious entries "." and "..".   Odd as it may seem, these are special directories which "point" to the current directory and the directory the current directory is in.  Try doing "ls ." and "ls ..".

One makes a new directory using the command "mkdir".  Suppose you're taking the course CS###.   It would make good organizational sense to have a directory for each CS class you take.  In each such directory, it would also make good sense to have a separate directory for each assignment you'll do.  Right now, you'll create these directories and learn to navigate among them.

First, create a directory for your coursework.  For example, if you're in cs111, enter the command "mkdir cs111".  Note that this is different than "mkdir cs111" or "MKDIR cs111".  Most UNIX commands, options, etc. are case-sensitive.  That is, case matters.  There are circumstances where capital letters are used by convention, but since you'll be typing directory names often and it's easier to type lowercase letters, it's generally a good idea to keep directory names short, descriptive, and in lower case.  After creating the directory, enter "ls" to verify that you created it as intended.

gbcs1:~$ mkdir cs111
gbcs1:~$ ls
cs111           public_html
gbcs1:~$

To change your current working directory to "cs111" (or whichever directory you created), use the command "cd", short for "change directory".  Enter the commands "cd cs111", "pwd", and "ls -a" in succession.

gbcs1:~/cs111$ cd ..
gbcs1:~$ cd cs111
gbcs1:~/cs111$ pwd
/Accounts/turing/students/s08/nuyuzr01/cs111
gbcs1:~/cs111$ ls -a
.       ..
gbcs1:~/cs111$

This is a brand new, empty directory.  What then are these odd hidden files "." and ".." doing here then?  These are actually special directories that point to directories.  "." points to the current directory.  ".." points to the directory the current directory is in.  Enter the commands "ls ." and "ls .." to verify this.

gbcs1:~/cs111$ ls .
gbcs1:~/cs111$ ls ..
cs111           public_html
gbcs1:~/cs111$

Why is this?  For one reason, it makes it possible to look at relative file paths rather than just absolute file paths.  The command "pwd" returns an absolute path.  A path name beginning with "~", ".", or ".." is a path relative to the home directory, current working directory, or directory above the current working directory, respectively.  In this current state, entering "ls ..", "ls ~", or  "ls /Accounts/turing/students/s08/nuyuzr01/" will yield the same result because these list the contents of the same directory using different ways of expressing the path to the home directory.  Now enter "cd" without specifying a directory and you will be returned to your home directory:

gbcs1:~/cs111$ cd
gbcs1:~$

Now it's time to introduce a very helpful feature of bash called completion.  With this feature, you'll be able to specify complex file paths with amazingly few keystrokes.  With completion, you can fly faster than you could ever image in the world of double-clicking folders.  Now type "cd c" but do not yet press Return.  Instead, press Tab.  Notice what happens.  Since there is one unique directory name (or filename) starting with "c", bash automatically completes the rest of the name for you.  When you press Tab, bash will seek to complete as much of the name as possible without further disambiguation.  This is a very nice feature which you'll appreciate more and more.  (Java filenames can be long.)   Now practice using completion to change to your course directory, and use both "cd .." and "cd ~" to change back to your home directory. 

If you're in a course that uses cvssetup for homework submission, and you've not already done so, you should set up your course homework directories for our CVS homework submission system.  For this, simply enter the command "cvssetup <course name> <course directory>", like this:

gbcs1:~$ cvssetup cs111 cs111

If you're in a course that instead uses Moodle for homework submission, you'll set up your course homework directories as needed.  For the first homework directory, create a subdirectory of "cs111" called "hw1" as follows:

gbcs1:~$ mkdir cs111/hw1
gbcs1:~$

Finally, change into your course directory and into your hw1 directory. 

gbcs1:~$ cd cs111
gbcs1:~/cs111$ cd hw1
gbcs1:~/cs111/hw1$

Note that we could have combined these into the single command:

gbcs1:~$ cd cs111/hw1
gbcs1:~/cs111/hw1$

Now let suppose you mistype and create a directory with the wrong name.  Enter the command "mkdir testt".  Suppose you meant the name to be "test".  There are two ways to take care of the problem.   The first is to move the directory from its incorrectly named location to its correctly named location.  In this case enter "mv testt test".  Remember that you can use completion ("t" then Tab) to speed your typing!  You could also remove the incorrect directory and try again.  The command to remove a directory is "rmdir", so enter "rmdir test" to try it now.

gbcs1:~/cs111$ mkdir testt
gbcs1:~/cs111$ mv testt test
gbcs1:~/cs111$ rmdir test
gbcs1:~/cs111
$

As a directory creation and navigation exercise, do the following:

To conclude this tutorial, we will now create a (nearly) empty webpage for your public_html directory.  If you're doing this tutorial as part of your first homework assignment, it would make sense to create this file in your hw1 directory.  Change to your "hw1" directory now.  There is a command that allows you to create a file by typing directly into a file.  Usually, one would use a text editor such as emacs to create a test file.  However, we'll leave emacs for a different tutorial.  For now, check that you're in your "hw1" directory and enter the command "cat > index.html".  Then enter the following lines, hitting Return after you've entered each line correctly:

<html>
<head>
<title>(Insert your name here.) CS Home Page</title>
</head>
<body>
This space intentionally left blank... for now.
</body>
</html>

When you've typed all these lines, press Control-d to mark the end of the file.  Then enter "ls" to see that the file has been created.  Finally, to see that the contents are what you expect, use completion to enter the command "more index.html" (type "more i" and press Tab).

gbcs1:~/cs111$ cd hw1
gbcs1:~/cs111/hw1$ cat > index.html
<html>
<head>
<title>Zralph Nuyuppy CS Home Page</title>
</head>
<body>
This space intentionally left blank... for now.
</body>
</html>
gbcs1:~/cs111/hw1$ ls
index.html
gbcs1:~/cs111/hw1$ more index.html
<html>
...
gbcs1:~/cs111/hw1$

We already know how to move a file or directory with the command "mv (source name) (destination name)".  To copy files, one uses the command "cp" in the same manner.  To copy this file to your "public_html" directory, you could use the command "cp index.html ~/public_html/".  Enter this command using completion: Type "cp i", Tab, "~/p", Tab, Return.  Notice how many keystrokes you save.  Now imagine that you're really comfortable with this environment and know a great many more commands.  If you go deeper in your understanding of UNIX and bash, you'll understand the meaning of the word "power" in the phrase "power user".   For now, continue your practice of completion and different equivalent file paths by entering these different forms of the same command:

gbcs1:~/cs111/hw1$ cp index.html ~/public_html
gbcs1:~/cs111/hw1$ cp index.html ../../public_html
gbcs1:~/cs111/hw1$ cp /Accounts/turing/students/s08/nuyuzr01/cs111/hw1/index.html ~/public_html
gbcs1:~/cs111/hw1$ cp ~/cs111/hw1/index.html ~/public_html
gbcs1:~/cs111/hw1$
 
But wait! There's more!  Look what you also get ABSOLUTELY FREE!...

This tutorial gives just a brief orientation to bash, but there is much more that can be learned.  If you have an interest in UNIX system administration (here or elsewhere), mastery of a shell such as bash is important and it is recommended that you go much deeper on your own.  Bash is the default shell for Linux and is growing in popularity on other UNIX systems.  Beyond UNIX, bash is also finding use on PCs.  Check out www.cygwin.com, and you'll see that bash can be installed under Windows (free).  Combined with the latest Java development kit and GNU emacs for the PC, you can have a very UNIX-like Java development environment on your home PC for free.  Cooool.

If you're doing this tutorial as a class exercise, type the command "(pwd; history) | cat >> README" in your homework directory. This will append a record of your work to a file called README which will be submitted with your assignment.

Now that you're well on your way to learning bash, the responsibility to learn more rests on your shoulders.  Remember that small time invested up front in this learning can save you much more time in the long run.  Also keep in mind that the computing habits you form now will stay with you for a career, so please take this independent learning seriously.  Not everything worthwhile should be assigned.  More in-depth UNIX and bash tutorials and references can be found on the CS Account Resources page.  Enjoy your learning!