Lab 8 - Intro to UNIX

CS3410 Fall 2016


Due: Complete the shell script at the end of this lab, and show it to your instructor in lab.

Instructions for getting the VM up and running

  1. Download and install both Vagrant and VirtualBox. Make sure you're running the latest version of both.
    If you're on Windows, make sure you have an SSH client installed. Installing Git is the easiest way to get an SSH client, and will be useful for this, and other courses! This website is very helpful for setting up vagrant on Windows: http://tech.osteel.me/posts/2015/01/25/how-to-use-vagrant-on-windows.html. (If you do not already have Git, when going through the setup, check the box "Use Git and optional Unix tools from the Windows Command Prompt" on the "Adjusting your PATH environment" screen. If you already have Git, you need to add the following to your PATH: C:\Program Files\Git\bin. You can do so by navigating to your system environment variables, and clicking edit "PATH".)

  2. Download the course VM from the github repo and install it. To get started, unzip the folder. Open up a Terminal/Command Prompt window. If you downloaded the VM into your "Downloads" folder, the path you might cd into might be something like ~/Downloads/vagrant-3410 on OS X/Unix or C:\Desktop\vagrant-3410 on Windows. Navigate into the VM folder, then call vagrant up. That might look something like the following:

    cd vagrant-3410
    vagrant up
    
  3. Once the vagrant up command has finished on your host machine, run vagrant halt. This will shutdown the virtual machine.

  4. Now if you need to work on 3410, cd back into the vagrant-3410 directory and run vagrant up. You now have to vagrant ssh, which will log you into the command line for an Ubuntu box that has what you need to completely destroy CS 3410 :).

  5. If you ls, you'll notice you have a folder 3410 within the VM. This folder will be mirrored on your VM and Host Machine! This allows you to work on files on your host, and compile and run them on the VM! Note: Always make sure to compile and run your code on the VM!

Using the GUI

If you are using the GUI shell, then you can access the vm by logging into the vagrant user.

username: vagrant
password: vagrant

Step 2. Directory structure

Directories in UNIX, much like other operating systems, are organized hierarchically. Now, we will learn to step through and modify our directory structure.

  1. Open up a terminal (VM specific)
  2. The current working directory is the directory in which the terminal is currently in. This current directory has a special name: ..
  3. Enter pwd (print working directory) to see the full path of this directory. If you just opened up the terminal, this directory should be /home/user, where user is your own username. This directory has a special name: ~.
  4. Enter ls to see the contents of the current directory. Try it now. To change the current directory, enter cd. This will step downwards in the directory hierarchy. To step back up the directory hierarchy, type cd ... .. is the name for the parent of the current working directory. To create a new directory, enter mkdir directory_name. To remove (empty) directories, type rmdir dirname.

Step 3. Files

In order to do anything useful, we need to learn how to perform basic file manipulation in the terminal.

  1. In your favorite text editor, copy and paste the following code:

    #include <stdio.h>
    int main() {
        printf("Hello World! \n");
        return 0;
    }
    

Navigate to your 3410 folder in your native OS, and create the folder hello_world there. Save the above code to your hello_world folder, under the name hello.c.

  1. In the terminal, navigate to the directory hello_world, inside of ~. Enter gcc hello.c -o hello. This command runs the gcc compiler, and creates the program hello inside of the current directory. You should see this program now if you ls.
  2. Run this program by typing ./hello. Remember that . is the name of the current directory, so ./hello is running the hello program inside of ..
  3. In order to create new files, type touch filename. This will create a new empty file filename inside of the current directory.
  4. In order to delete files, type rm filename. Create a few files inside of hello_world using touch, and delete them.
  5. You can copy files using cp: cp infile outfile will copy the contents of infile into outfile (overwriting if outfile already exists). cp infile dir will make a copy of infile inside of dir, if dir is a directory.
  6. To move files, use mv: mv file dir will move file to the directory dir.

Step 4. More Files

  1. Enter less filename to view files inside of the terminal. You can scroll up and down with the arrow keys, and type q to exit back to the terminal.
  2. cat file will display the contents of file to the terminal. echo text will echo text to the terminal.
  3. The output of cat and echo is stdout, which by default prints to the terminal. However, we can redirect this output into files: P > f.txt will overwrite the contents of f.txt with the output of program P (creating f.txt if it doesn't already exist). P >> f.txt will append the output of P into f.txt, but doesn't overwrite anything.
  4. Use cat and > to create a new file with the same contents as hello.c.
  5. Many commands which run on files (such as cat or wc), when given no file as input, will instead read input from stdin, which is user input from the terminal. They will continue running until you issue them an end-of-file character, produced with ^D. For example, run cat, type in some input ending with a newline, and hit ^D. You should see your input returned back at you.
  6. Further, we can redirect stdout from one program into stdin into another; this is called piping. The syntax of this is P | Q, which redirects the output of P into Q. For example, try out echo abc | cat. Piping is very useful for automated testing: if I have a program that receives parameters from stdin, you can echo those parameters and pipe them into your program.

Tips and Tricks

  1. Modern terminals such as bash support tab completion. While typing a command, press tab once and the terminal will autocomplete your command, if there is only one choice. If there is any ambiguity, press tab twice and the terminal will present a list of possible commands you may be typing. Tab completion also works for files and directories: inside of ~/3410, type (but don't enter) cd hello, and then press tab; your command should autocomplete to cd hello_world.
  2. You can use the up and down arrow keys inside of the terminal to browse previous commands entered. history will give you a full history of these commands.
  3. Ctrl-C (written ^C) will send an interrupt command to the currently running program, which will attempt to halt it and restore control back to the terminal.
  4. A short list of other commands you might eventually need to know about (not necessarily for this class): grep, find, kill, scp, ssh, su, tar, whereis, df, aspell. Knowing how to use piping (discussed above) with grep is particularly useful.

Step 5. Shell Scripting

Note: man command will open up the manpage for command, which gives some documentation on each command. If you are unsure of how to use a command, use man to open up its manual page.

  1. Briefly view the manpages for all of the commands discussed above (and continue to do so below).
  2. In order to automate terminal commands, we can create shell scripts which will automatically run commands for us. Shell scripting is fully-featured, so we can make use of variables, loops, and so on.
  3. Copy and paste the following into a new file, script.sh:

    #!/bin/bash
    echo This is a shell script
    

    The top line is called a shebang, and tells the environment what program to run the code in. (This same format can be used to execute programs in python, perl, awk, etc).

  4. Try to run it. You should see a Permission Denied error. That's because the environment doesn't yet know that script.sh is meant to be executable. To change this, use chmod: chmod +x file will set file to have executable permissions (+x for eXecute).
  5. Now, run the file after chmod; you should see This is a shell script.
  6. To set variables, type var=value; note the lack of spaces. To refer to the value of the variable, type $var. Simply typing var will not refer to any variable, but rather the text var. That is, var=3; echo var will output var, but var=3; echo $var will output 3. (Multiple commands can be run on one line by separating them with semicolons.)
  7. To refer to the output of a program in a script, enclose the program in backticks: var=`seq 3` will set var equal to the string 1 2 3. (Type man seq to see how seq works.)
  8. Refer to Section 6 and 7 of this guide for the implementation of loops and conditionals. For loops work over the "words" in the input, where "words" are separated by spaces. For example,

    for i in `seq 3`; do
        echo $i
    done
    

    will output

        1
        2
        3
    
  9. Variables 1 through 9 refer to the command line arguments of the script. For instance, echo $1 will echo the contents of the first argument. Command line arguments are separated by spaces.

  10. Throughout the above, the values of variables are treated as pure text. In order to treat variables as numbers, enclose them in double parentheses. For example,

    v=2
    echo $v+2
    

    will output 2+2, but

        v=2
        echo $((v+2))
    

    will output 4.

  11. Using all of the above, write a bash script total.sh that takes as input a file containing a list of integers, and outputs the running total of these integers. For example, if the contents of ints is 1 2 3 4 5, ./total.sh ints would output 1 3 6 10 15 (perhaps with newlines instead of spaces). In order to do this, you will need to use a for loop along with cat to iterate over the integers in the file. Show your lab TA your script once you are finished.