The interpreter
Running a script.
A shell script is just the commands in a file like:
$ cat bs1
who | wc -l
We can run it by typing the command name. script like:
$ bs1
bs1: execute permission denied
Well, first the execute permission must be set with chmod.
$ ls -al bs1
-rw-r--r-- 1 xxam225 12 Jun 21 10:16 bs1
$ chmod a+x bs1
$ ls -al bs1
-rwxr-xr-x 1 xxam225 12 Jun 21 10:16 bs1
$ bs1
7
Comments.
A comment is started by # at the beginning of a word.
Comments ends at the newline.
$ cat bs3
# Test script
echo Users # heading
who | wc -l # command
$ bs3
Users
11
Variables.
- Variables in shell scripts hold values.
- Variable names begin with a alphabetic or underscore ( _ ), and is followed
by zero or more alphanumeric or underscore characters.
- Variable names are case sensitive. So cat and Cat are different variables.
- Variables are assigned values by the = operator.
- The value of variables may be displayed by using the echo command. A $
before the variable name tells the shell to use the value of the
variable not its name.
- Examples
$ cat bs4
# Variable test cases
one=zap
echo Test case 1 $one
echo Test case 2 one
echo Test case 3 :$ONE:
two = zip # note the space in the assignment
echo Test case 4 :$two:
three= zoom # note the spaces
echo Test case 5 :$three:
$ ./bs4
Test case 1 zap
Test case 2 one
Test case 3 ::
./bs4[6]: two: not found.
Test case 4 ::
./bs4[8]: zoom: not found.
Test case 5 ::
- To create a new value from a variable name use the ${variable} construct.
To copy a file name in variable file to one with the same name with
an X suffix.
$ cat bs5
# Variable test cases
file=bs1
echo " cp $file $fileX"
echo " cp $file ${file}X"
$ bs5
cp bs1
cp bs1 bs1X
Quotes
The Bourne (Korn, Bash and C) shell uses four different quoting mechanisms.
The single
quote ' , the double quote " ,
the backslash \ and the backquote ` .
The main reason for using quotes is to keep characters together that
are separated by whitespace or to prevent the shell from using a
metacharacter.
- ' The single quote.
-
$ grep Allan Kochis /etc/passwd
grep: Kochis: No such file or directory
/etc/passwd:xxam225:guVC19th4z.6M:1123:50:Allan Kochis:/home/xxam225:/bin/csh
$ grep 'Allan Kochis' /etc/passwd
xxam225:guVC19th4z.6M:1123:50:Allan Kochis:/home/xxam225:/bin/csh
The single quote is the most restrictive. All special (meta characters) are
ignored within single quotes.
$ cat bs6
file=bs6
ls -l $file
ls -l '$file'
$ bs6
-rwxr-xr-x 1 kochis staff 35 Oct 16 15:19 bs6
ls: 0653-341 The file $file does not exist.
- " Double Quote
-
Double quotes are similar to single quotes in keeping characters
together, but they are less restrictive. Single quotes ignore all
special characters. Double quotes allow dollar sign($), backquotes (`)
and backslashes (\) to be evaluated.
$ cat bs7
file=*
ls -l $file
ls -l '$file'
ls -l "$file"
$ bs7
-rwxr-xr-x 1 kochis staff 255 Oct 16 15:15 bs4
-rwxr-xr-x 1 kochis staff 49 Oct 16 15:23 bs7
-rw-r--r-- 1 kochis staff 70373 Sep 24 05:34 doc
-rw-r--r-- 1 kochis staff 408 Aug 31 16:20 junk
-rw-r--r-- 1 kochis staff 1131 Aug 08 20:15 netpulse
-rwxr-xr-x 1 kochis staff 1459 Aug 08 16:26 newdoc
ls: 0653-341 The file $file does not exist.
ls: 0653-341 The file * does not exist.
- \ Backslash
-
This is the same as putting single quotes around
a single character.
$ cat bs8
file=*
ls $file
ls \$file
$ bs8
-rwxr-xr-x 1 kochis staff 255 Oct 16 15:15 bs4
-rwxr-xr-x 1 kochis staff 49 Oct 16 15:23 bs7
-rw-r--r-- 1 kochis staff 70373 Sep 24 05:34 doc
-rw-r--r-- 1 kochis staff 408 Aug 31 16:20 junk
-rw-r--r-- 1 kochis staff 1131 Aug 08 20:15 netpulse
-rwxr-xr-x 1 kochis staff 1459 Aug 08 16:26 newdoc
ls: 0653-341 The file $file does not exist.
- `The backquote
-
The backquote is different than the other quotes. It instructs the
shell to execute the command in the backquotes and insert the standard
output between the back quotes.
$ cat bs9
echo There are `ls -1 |wc -l ` files
day=`date | tr ' ' ':' | cut -d: -f1`
echo Today is $day
$ bs9
There are 33 files
Today is Mon
Shell Arithmetic.
In order to do arithmetic on shell variables, the expr
command must be used.
The expr command reads the expression parameter, evaluates it, and
writes the result to standard output.
You must apply the following rules to the Expression parameter:
- Separate each term with blanks.
- Precede characters special to the shell with a \ (backslash).
- Quote strings containing blanks or other special characters.
- Integers may be preceded by a unary hyphen. Internally, integers are
treated as 32-bit, twos complement numbers.
$ cat bsa
echo example 1. `expr 1 + 3`
echo example 2. `expr 1+3`
echo example 3. `expr 20 + 20 / 2`
echo example 4. `expr 4 * 2`
echo example 5. `expr "4 * 2"`
echo example 6. `expr 4 \* 2`
i=2
i=`expr $i \* 2`
echo example 7. $i
$ bsa
example 1. 4
example 2. 1+3
example 3. 30
expr: syntax error
example 4.
example 5. 4 * 2
example 6. 8
example 7. 4
Parameters
Parameters can be used extend the shell script to specify data a run time.
If we had a shell that compiled a c program like:
$ cat comp
#!/bin/sh
echo Compiling signal
cc -o signal signal.c
$ comp
Compiling signal
And we wished to write it so we could compile any c program, we could
change the shell to accept a parameter like:
$ ls *.c
dir.c signal.c test.c
$cat comp
#!/bin/sh
echo Compiling $1
cc -o $1 $1.c
$ comp signal
Compiling signal
$ comp test
Compiling test
$ comp dir
Compiling dir
The parameter variables set when the shell executes are:
- $#
This is set to the number of arguments passed to the script.
$ cat bsb
echo $# arguments
$ bsb one
1 arguments
$ bsb one two
2 arguments
$ bsb "one two"
1 arguments
$ bsb *
33 arguments
- $*
This is the entire argument line (all of the arguments).
$ cat bsd
echo $# arguments
echo :$*:
$ bsd one
1 arguments
:one:
$ bsd one two
2 arguments
:one two:
$ bsd "one two"
1 arguments
:one two:
$ bsd *
33 arguments
:Cancelled.mail Mail News accounting awk bin bsd c cal cerb clips cpr
fortran ftp hli infosys misc nu_tpu.def othello outline pas pascal problems
sql tcp tdb text typescript users xd xwclass zeta zeta_sample:
- $1..$9
Numbered arguments 1 through 9 match the first nine positional arguments.
$ cat bse
echo $# arguments
echo First :$1:
echo Second :$2:
echo Third :$3:
$ bse one two
2 arguments
First :one:
Second :two:
Third ::
$ bse one two "three four" five
4 arguments
First :one:
Second :two:
Third :three four:
- shift
The shift command makes it possible to access more than nine arguments.
shift will remove $1, then make $2 $1, then make $3 $2 and so on. Shift also
changes $#.
$ cat bsf
echo $# arguments
echo First :$1:
echo Second :$2:
echo Third :$3:
shift
echo $# arguments
echo First :$1:
echo Second :$2:
echo Third :$3:
$ bsf one two three four five
5 arguments
First :one:
Second :two:
Third :three:
4 arguments
First :two:
Second :three:
Third :four:
Shift can shift multiple positions with a specified number. So shift 3
is the same as shift shift shift.
$ cat bsg
echo $# arguments
echo First :$1:
echo Second :$2:
echo Third :$3:
shift 2
echo $# arguments
echo First :$1:
echo Second :$2:
echo Third :$3:
$ bsg 1 2 3 4 5 6
6 arguments
First :1:
Second :2:
Third :3:
4 arguments
First :3:
Second :4:
Third :5:
If you try to shift when $# is zero. Here is what happens:
$ bsg 1
1 arguments
First :1:
Second ::
Third ::
bsg: cannot shift