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?
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.
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 &
.
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
#!/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.