A shell script is a file including a list of executable commands that the UNIX shell executes one by one. (We've seen something similar in the last lab with sed scripts - sed commands that are stored in a file and executed one by one by sed.)
To execute a script, the script must have execute permission turned
on. You can do this with the
chmod
command:
chmod u+rx scriptfile
Now that the script has the proper permssions, call it by giving its
directory and name. If the script file is in the current directory,
you must provide that information by putting
./
in front of the script name:
./scriptfile
A shell script may contain multiple commands. Commands are generally
listed one to a line. Longer commands may be extended by ending the
line with a backslash (
\
), as in sed scripts. Commands may include just about anything that
you can type at the commend prompt.
The
who
command displays information about who is currently logged into the
system:
who Sample Output/home/dbrown/CP367> who root console Feb 24 16:05 (:0) choang pts/2 Feb 28 09:21 (tipa.wlu.ca) dbrown pts/3 Mar 1 10:33 (dbrown.wlu.ca) mieh8930 pts/6 Mar 1 10:04 (172.21.29.83) mieh8930 pts/7 Mar 1 10:07 (172.21.29.83) root pts/5 Feb 24 16:06 (:0.0) root pts/8 Feb 24 16:16 (:0.0) choang pts/9 Mar 1 10:50 (216.249.63.201) klem5550 pts/10 Mar 1 10:47 (cpe00222d181f0d-cm00222d181f09.cpe.net.cable.rogers.com) kimx1990 pts/11 Feb 28 09:34 (tipa.wlu.ca) kimx1990 pts/12 Feb 28 09:35 (tipa.wlu.ca) eric8260 pts/13 Mar 1 11:04 (cpe0026f30d50f1-cm0026f30d50ed.cpe.net.cable.rogers.com) mieh8930 pts/17 Mar 1 10:04 (172.21.29.83) wang6470 pts/18 Feb 28 09:59 (tipa.wlu.ca)
The script
newwho
modifies and formats the output of the
who
command:
#!/bin/sh echo "WLU Connections" who | grep wlu.ca echo "------------------------------------------------" echo "Non-WLU Connections" who | grep -v wlu.ca exit 0
and when executed, produces:
/home/dbrown/CP367> ./newwho WLU Connections choang pts/2 Feb 28 09:21 (tipa.wlu.ca) dbrown pts/3 Mar 1 10:33 (dbrown.wlu.ca) kimx1990 pts/11 Feb 28 09:34 (tipa.wlu.ca) kimx1990 pts/12 Feb 28 09:35 (tipa.wlu.ca) wang6470 pts/18 Feb 28 09:59 (tipa.wlu.ca) ------------------------------------------------ Non-WLU Connections root console Feb 24 16:05 (:0) mieh8930 pts/6 Mar 1 10:04 (172.21.29.83) mieh8930 pts/7 Mar 1 10:07 (172.21.29.83) root pts/5 Feb 24 16:06 (:0.0) root pts/8 Feb 24 16:16 (:0.0) choang pts/9 Mar 1 10:50 (216.249.63.201) klem5550 pts/10 Mar 1 10:47 (cpe00222d181f0d-cm00222d181f09.cpe.net.cable.rogers.com) eric8260 pts/13 Mar 1 11:04 (cpe0026f30d50f1-cm0026f30d50ed.cpe.net.cable.rogers.com) mieh8930 pts/17 Mar 1 10:04 (172.21.29.83)
There are many different shells available, such as
sh
,
ksh
,
csh
, and of course,
bash
. The first line of a script should identify the shell the script
should run under. The shell
sh
is the original, 'base' shell, and any script that runs under
sh
meets the POSIX
standard. Such scripts are portable to most unix or Linux systems.
Such a script starts with the
#!/bin/sh
she-bang. (she from sharp (
#
) and bang from and bang (
!
) character). You may refer to other shells if you intend to use
those shell's capabilities, but the resulting scripts will not be as
portable. Note that the
#
character identifies this first line as a comment.
Scripts should end with the
exit
command. This command is generally followed by a number that
indicates whether the script was successful or not. A
0
indicates the script ended with no errors, whereas any other number
should indicate the kind of error that occurred. Simple scripts that
cannot cause an error under normal circumstances should always end
in
exit 0
. This exit status value can be checked by other scripts.
echo string|$variable
read variable
The
getstring
script:
#!/bin/sh echo "String: " read string echo "The entered string was: $string" exit 0
and its execution:
/home/dbrown/CP367> ./getstring String: Hey there! The entered string was: Hey there!
When are there actual differences between shells?
getstring2
starts with
#!/bin/bash
rather than
#!/bin/sh
.
bash
supports the
-n
option for echo (i.e. do not add a new line),
sh
does not:
#!/bin/bash echo -n "String: " read string echo "The entered string was: $string" exit 0
when executed:
/home/dbrown/CP367> ./getstring2 String: Look at this! The entered string was: Look at this!
Shell variables are similar to variables in most programming languages that you are familiar with. You may assign values to variables, perform simple calculations on them, use them in control structures (ifs and loops), and display their values. There are a number of predefined and special variables available.
Variable names must start with a letter. Variable names that start with a number are special argument variables that are assigned by the system.
Values are assigned to 'naked' variable names - i.e. the variable
name does not have a
$
in front. Values are assigned with the
=
character. Do not put spaces between the variable name, the
=
, and the value. Values that contain spaces must be enclosed in
double quotes. Examples:
var1=5
var2="Some String"
var3 = 6 # Invalid assignment
You may assign the output of a command to a variable by putting the
command within single back quotes (
`
). This executes the command and puts the result into the variable,
as in this example:
/home/dbrown/CP367> HOST=`hostname` /home/dbrown/CP367> echo $HOST hopper
Variables can be used within scripts and strings, but may have to be escaped in certain circumstances. If a variable is used within spaces, then nothing special needs to be done to display it:
/home/dbrown/CP367> echo "The machine is $HOST" The machine is hopper
Without spaces, the variable must be enclosed within brace brackets
(
{}
), as in the creation of the
FULLNAME
variable in the following script
hostinfo
:
#!/bin/sh
# Ask the user for the Internet domain.
echo "Enter domain:"
read DOMAIN
# Get the name of the machine from the system.
HOST=`hostname`
# Generate the full name.
FULLNAME=${HOST}.${DOMAIN}
echo "Machine name is $FULLNAME"
# Test the full name with 'ping'.
PINGRESULT=`ping $FULLNAME`
echo $PINGRESULT
exit 0
When executed:
/home/dbrown/CP367> ./hostinfo Enter domain: wlu.ca Machine name is hopper.wlu.ca hopper.wlu.ca is alive
Note that variables can be defined both at the command line and
inside scripts. Variables defined at the command line remain in
existence for the rest of the session. Variables defined inside a
script only exist as long as the script is running. Scripts can
refer to command line variables, but will have an error if the
command line variable does not exist. Use the
set
command to list all variables defined or pre-defined from the
command line.
There are a number of typical pre-defined variables available on a
given system. One such variable is
$HOME
, which identifies the home directory of the current user. It can be
displayed or used in commands:
/home/dbrown/CP367> echo $HOME /home/dbrown /home/dbrown/CP367> ls $HOME a1.zip example.txt newwrap.sed old.txt public_html stuff.txt wraphtml.sed CP367 fix.sed noblank.sed out.txt script.sed test.txt error.txt good.txt noblank.sh p.sed sed text2html.sh
You can pass arguments to scripts. You may then determine the number and values of these arguments with system-defined variables:
$0
$#
$@
$1 .. $n
$#
.
These argument variables are particularly useful when you know the number of arguments to expect, or intend to loop through the arguments and process them.
The script file
vars1
demonstrates a number of the variable handling mentioned:
#!/bin/sh # Get the name of the script. echo "The name of the script is in \$0" echo "Name of script: $0" echo # Get the number of arguments to the script. echo "The number of arguments passed is in \$#" echo "Number of arguments: $#" echo echo "The arguments are in \$1 through \$$#" echo echo "The arguments are stored in \$@" echo "$@" echo echo "The arguments are stored in \$*" echo "$*" echo # Call a system command and send the result to a variable. arch=`uname -m` echo "System architecture: $arch" echo # Set a variable to a numeric value. n=5 echo "\$n = $n" echo # Miss-set a variable. m = 9 echo "\$m = $m" exit 0
Executing
vars1
without arguments:
/home/dbrown/CP367> ./vars1 ./vars1: Get: not found The name of the script is in $0 Name of script: ./vars1 The number of arguments passed is in $# Number of arguments: 0 The arguments are in $1 through $0 The arguments are stored in $@ System architecture: i86pc $n = 5 ./vars1: m: not found $m =
Executing
vars1
with arguments:
/home/dbrown/CP367> ./vars1 stuff and nonsense ./vars1: Get: not found The name of the script is in $0 Name of script: ./vars1 The number of arguments passed is in $# Number of arguments: 3 The arguments are in $1 through $3 The arguments are stored in $@ stuff and nonsense System architecture: i86pc $n = 5 ./vars1: m: not found $m =
Create a shell script doing the following (call it
task1
):
output.txt
file and errors to the file errors.txt.
Create a shell script for submitting your homework (call it
submit
):
submit two arguments:
/tmp)