A little bit of UNIX

First of all a general knowledge quiz for you about UNIX. Here are the answers.

1) Who originally wrote UNIX?

In the following questions write the UNIX command which:

2) Tells you who you are.

3) Tells you where you are (in the file directory system).

4) Creates an empty file called foo in the current directory.

5) Creates a directory called bar in your home directory.

6) Joins two files foo and bar and puts the joined data into a file called zan.

7) Deletes all files in the current directory.

8) Move to the directory two levels above the current one.

9) Copy all the contents of directory foo to directory bar.

10) Stop the currently running foreground process and restart it in the background.

11) Find and display all lines which contain either foo or Foo in the file bar.

12) Display the first and the last lines of file foo.

13) Display the first 5 characters in each line of file foo.

14) Remove all occurrences of the string foo from the file bar.

Different sorts of questions now.

15) In what way do the file access bits need to be different on an executable shell script compared to an executable binary file?

16) Why can't I make my program called test run?

Answers

1) Ken Thompson and Denis Ritchie

2) whoami

3) pwd

4) cat /dev/null > foo

5) mkdir ~/bar

6) cat foo bar > zan

7) rm *

8) cd ../..

9) cp foo/* bar

10) Ctrl-Z followed by bg

11) grep [fF]oo bar

12) head -1 foo; tail -1 foo

13) cut -b1-5 foo

14) sed 's/foo//g' bar > temp; mv temp bar

15) shell scripts need to be readable as well as executable

16) test is a command built-in to the the shell. Use ./test instead.

Nice things about the bash shell.

File name and command name completion. (Saves time and can help when you don't know what you are doing.)

When you remember the start of a command but can't remember any more you can type the first bit and then hit the tab key. Bash will go off and look through your command path and try to complete the command. If there is only one command that makes sense the rest of the command will be filled in automatically. If there is more than one you will be beeped, if you type tab again a list of all possible completions will be given.

Built-in help. Type help to see.

Job control. Ctrl-Z is usually set up to stop the currently running job. The jobs command gives a list of users current jobs. Each job has an associated number (this is a simple integer, starting with 1, unique for each user, but not across users, unlike process ids). A job can be moved to the background (which means it continues to run with bg. Of course a job can be started in the background by ending the command with &.

Concepts of UNIX

Pipelines and filters

Possibly the cleverest thing about UNIX is the way that commands were originally designed to do one thing (or type of thing) but by connecting a string of commands together you can do almost anything.

Say for example I want to find out how many people are currently logged in.

who | wc -l

and

spell -b disneyland | sort -uf | wc -l

Some shell script stuff

#!/bin/bash

This tells the operating system (yes the operating system) that the rest of this file is a bash shell script. Then we can chmod u+x the file and can run it merely by typing its name. UNIX checks all executable files to see that type they are by looking for their magic numbers (which are stored in the first few bytes of the file). The #! says this file needs to be interpreted, the following pathname show interpreted by what.

If we want to check to see if there are any command line parameters passed to the script we commonly use:

if [ -z "$1" ] ; then

echo $0: usage: $0 blah

exit 1

fi

There are all sorts of things to take note of here:

The use of [] instead of test.

The -z means "is it empty?"

$1 means the first command line parameter.

The quotes are necessary, can you tell me why?

The ; could have been left out if the then was on a new line.

$0 is the command name itself.

exit 1 means an error return (anything non-zero is an error).

#!/bin/bash

while [ ! -z "$1" ] ; do

if [ ! -r $1 ] ; then

echo $0: no $1 file.

shift

continue

fi

if [ ! -w `dirname $1` ] ; then

echo $0: I cannot delete $1.

shift

continue

fi

lpr $1

rm $1

shift

done

exit 0

Things have traditionally gotten nasty when asking the Bourne shell to do arithmetic, things are a little nicer with the bash shell.

#!/bin/bash

echo I can count to ten.

number=0

while [ $number -lt 10 ] ; do

number=$(($number + 1))

echo $number

done

One last simple one to demonstrate the for construct:

#!/bin/bash

for name in `cat fileOfNames` ; do

banner $name

done

Of course fileOfNames has to exist, you can add the necessary checks.

Back to lecture index

Next lecture