There are two main flavours of shells, the Bourne-shell (sh, ksh,
bash) and the C-shell (csh, tcsh). An example of a Bourne-shell script
is tofloppy
:
#!/bin/sh
gzipped="false"
dev="/dev/fd0"
if [ $# -eq 1 ]; then
case ".$1" in
.*.gz|.*.tgz)
gzipped=true ;;
.*) ;;
esac
fi
if [ ".$1" = ".-9" ]; then
gzarg='-9'
shift
else
gzarg='-5'
fi
if [ "$gzipped" = "true" ]; then
echo "This will put the gzipped item $1 to the floppy disk."
echo 'Insert the floppy disk and press Return when done.'
read ans
cat $1 | dd bs=8192 of="$dev"
else
echo "This will put items $* to the floppy disk."
echo 'Insert the floppy disk and press Return when done.'
read ans
tar cfv - $* | gzip $gzarg | dd bs=8192 of="$dev"
fi
echo 'tofloppy ok. See fromfloppy [-t] for reverse operation.'
Put this in directory bin
under your home directory (do mkdir
bin
if it does not yet exist), naming the file tofloppy
, and
give execution permission: chmod +x tofloppy
. Then ensure that
$HOME/bin
is in your PATH (see
PATH).
After this, tofloppy is available as a command (after
doing rehash
if using csh or tcsh). Tofloppy
is given a list
of file or directory names; it makes a gzipped tarfile out of those
and writes it to your floppy disk. The option -9
is recognized,
it tries to compress harder. For user convenience, if only one argument is given and if it
ends with .gz
or .tgz
, it will be written directly to disk,
without tarring and compressing it first, since it is already in
compressed form.
The used shell is specified in the first line reading
#!/bin/sh
. Since this line starts with #, the
shell treats it as a comment, but the Unix kernel uses the information
to execute the file using the program /bin/sh
. The program
name must be a full, explicit pathname here. This is sometimes a
nuisance for portability, if the pathname is different on different
system. One can trust that sh
is always found in /bin
,
this is one reason why I prefer Bourne shell scripts.
A corresponding program fromfloppy
looks the following:
#!/bin/sh
opts="xvfo"
showingOnly=false
if [ $# -eq 1 ]; then
if [ "$1" = "-t" ]; then
opts="tvf"
showingOnly=true
fi
fi
if [ "$showingOnly" = "true" ]; then
echo "This will show the directory on your floppy disk."
else
echo "This will extract the files from your floppy disk."
echo '(Use fromfloppy -t to see the directory only.)'
fi
echo 'Insert the floppy disk, press Return when done.'
read ans
dd bs=8192 if=/dev/fd0 | gunzip | tar $opts -
echo 'fromfloppy ok. See tofloppy for reverse operation.'
fromfloppy
reads a compressed tarfile stream from the floppy disk
(it prompts the user to press Return first) and unpacks the files in
the current directory. fromfloppy -t
only shows what files are
there without actually extracting them.
A summary of the shell syntax can be found in the man pages. The only
problem is that the man pages are very long. Thus it is better to grab
them in a text file first, by doing e.g. man sh | col -b
>mansh
and viewing mansh
in your favourite text editor.
In bash
, a quick help is available by typing help
.
The oldest of the shells is the original Bourne-shell, sh
. It
does not provide interactive sugar such as command line editing or TAB
completion (command and filename completion by pressing TAB). The
Korn-shell ksh
is a somewhat-extended version which is the
default on HP workstations, for instance. The GNU version is called
Bourne-again shell (bash
). It provides many nicety features while
being compatible with the original Bourne-shell and is often the
default shell on Linux systems. On Linux, /bin/sh
is a
symbolic link to /bin/bash
.
The C-shell has a different syntax for if-statements, loop statements
and so on. The original C-shell does not have command line editing and
is thus not suitable for interactive work. The tcsh
contains
these facilities. I usually use tcsh
as my interactive shell but
/bin/sh
for my scripts.
A summary of the input/output direction commands in different shells:
prg <input >output # (all shells) stdin from input, stdout to output
prg 2>/dev/null | less # (Bourne-shell) ignore error output, pipe stdout to less
prg 2>&1 >x # (Bourne-shell) stdout and stderr to x
prg >&x # (csh,tcsh) stdout and stderr to x
(prg >x) >&y # (csh,tcsh) stdout to x, stderr to y
tcsh
and bash
A program can be running in the foreground, in the background, or be
in suspended state (stopped but restartable). To run the program in the
background one ends the command with &. It is also possible to put
a foreground job to the background by first suspending it by pressing
Control-z
and then typing bg
. Inversely, a background job
can be brought to foreground by typing fg
. Thus it is not
necessary to restart the program just because one wants it to run in
the background. On modern systems, background jobs are usually not
killed if the shell that created them exits.