1 CS112: Computing Environments (18)
¯ Unix Shell Programming ¯ Programming the Bourne Shell
2 Shell programs
¯ The are a number of alternate shells, tcsh, csh, sh, ksh, bash ¯ All of these shells have a programming language embedded in them ¯ Shell programs are interpreted (no compiler) ¯ Shell programs are files containing commands which the shell reads and executes immediately. ¯ The sh and csh families of shells have different syntax. ¯ We are looking at the sh programming language
3 An example shell program
¯ Here is an example program
#! /bin/sh # This is a simple program to print to the screen echo "Hello, this is a shell program" exit 0
¯ Lines beginning with the # (hash) symbol are comments ¯ The first line of the file is a special comment. It tells the name of the shell program that will execute the program. ¯ There is one command in this program, echo ¯ The final line exits the program.
4 Calling Unix commands in Shell programs
¯ Any executable program that is in a directory contained in your PATH can be called from a shell program. ¯ You can set a PATH variable within the program. ¯ You can specify the full path name to any command if there is no PATH
1
5 Bourne Shell Variables
¯ Setting a variable within a shell program: VAR=value ¯ For example: NAME=’tony’ ¯ Refering to the value of a variable needs a $ symbol in front of the variable’s name. ¯ For example: echo ’My Name is ’ $NAME ¯ Variables do not have to be declared and do not have a type:
#! /bin/sh NAME=’tony’ echo ’My name is ’ $NAME NAME=5 echo ’My name is ’ $NAME exit 0
6 Running shell programs
¯ We can run a shell program by invoking the shell with the filename as an argument. ¯ If we have an shell program called example.sh, we can run it using: sh example.sh ¯ We can make the shell program an executable command by adding x permission to its file permissions: chmod u+x example.sh ¯ Now we can execute the program by just typing its name: example.sh ¯ I will put .sh at the end of the filename for all my shell programs. That is not necessary, but indicates the file is a bourne shell program.
7 Command Line Arguments
¯ Some programs accept or require command line arguments. ¯ In a shell program we can access the command line arguments using the variables $1, $2, . . . ¯ $1 refers to the first argument ¯ $2 refers to the second argument, etc ¯ $0 refers to the name of the program
2
8 Using Command Line Arguments
¯ Here is a program that simply prints out its own name and the name of its first argument:
#! /bin/sh NAME=$0 ARG1=$1 echo ’This program is called ’$NAME’ and its first argument is ’$ARG1 exit 0
¯ We don’t necessarily need to assign the arguments to other variables:
#! /bin/sh echo ’This program is called ’$0’ and its first argument is ’$1 exit 0
¯ If there is no argument, the variable has a null value
9 Using if-then-else-fi
¯ If we use command line arguments, we need to test if they exist. ¯ The Bourne shell has an if-then-else-fi construct:
#! /bin/sh if test $1 then echo ’Argument 1 is ’$1 else echo ’There is no first argument’ fi
¯ The if part needs a test ¯ If the test evaluates to true, the then part is executed ¯ If the test evaluates to false, the else part is executed ¯ We need to put fi to indicate where the if finishes ¯ You may see the test written using square brackets: if [ $1 ] ¯ If you use square brackets, they need spaces around them
10 Finding out how many arguments there are
¯ The special variable $# holds the number of arguments ¯ To test equality, the test uses -eq ¯ To test inequality, the test uses -ne
3
¯ For example: if test $# -ne 1 if test $# -eq 3 ¯ Here is an example program showing how to deal with arguments:
#! /bin/sh if test $# -ne 1 then echo ’Error, wrong number of arguments’ echo ’Usage: ’$0’ arg’ exit 1 else echo ’Yes, one argument is correct’ fi exit 0
11 Executing other programs
¯ We can execute other programs in a shell:
#! /bin/sh ls -l exit 0
¯ What if we want to put the result of the program into a variable ¯ For example, lets collect the output from ls in a variable and pass those file names to the fgrep program. ¯ The following will not work:
#! /bin/sh FILES=ls fgrep ’FILES’ ${FILES} exit 0
12 Using the backticks
¯ What we want to do is execute ls first, before assigning its output to a variable. ¯ To execute a command we enclose that command in backticks: FILES=‘ls‘ ¯ Do not confuse backticks with single quotes – they are different ¯ Here is the correct program:
#! /bin/sh FILES=‘ls‘ fgrep -l ’FILES’ ${FILES} exit 0 4
13 The expr command
¯ The expr command will evaluate expressions ¯ expr is a bit like test, it evaulates something and returns true or false ¯ We can evaluate mathematical expressions using expr ¯ For example, to add two numbers: expr 4 + 6 ¯ We can also do string comparisons using expr: if expr "$myname" = "Tony" ¯ Notice that even variables need to be put into double quotes to be treated as strings
14 Evaluating Mathematical Expressions
¯ Here is an example of evaluating mathematical expressions
#! /bin/sh if test $# -ne 2 then echo ’You need two arguments’ echo ’Usage: ’$0’ arg1 arg2’ else SUM=‘expr $1 + $2‘ echo ’Sum is ’${SUM} fi exit 0
15 String Comparison
¯ Here is a program to do a string comparison on its argument:
#! /bin/sh if test $# -ne 1 then echo ’You need one argument’ echo ’Usage: ’$0’ arg1’ else if expr "$1" = "Tony" then echo ’Hello Tony’ else echo ’Sorry, I dont know you’ fi fi exit 0
5
16 What is that ’1’ or ’0’ from
¯ When we run the program on the previous slide, we get a 1 or a 0 printed out before the text that is echoed. ¯ For example:
prompt> namecheck.sh Tony 1 Hello Tony prompt>
¯ And:
prompt> namecheck.sh fred 0 Sorry, I dont know you prompt>
¯ This text is actually the result of the whatever expr evaluated. ¯ In the mathematical example we wanted the result returned ¯ In this case, we should throw away the result
17 Redirecting unwanted text
¯ We recall that there is a redirection operator in Unix: > ¯ We could redirect the output from expr into one of our own files: if expr "$1" = "Tony" > ./junk ¯ But we’d have this junk file lying around ¯ There is a special unix file for sending unwanted text called /dev/null ¯ We can rewrite the expression test as: if expr "$1" = "Tony" > /dev/null
18 Redirecting the Error output
¯ Occasionally, commands give out error messages ¯ The > operator will redirect the standard output ¯ Error messages are send to the standard error ¯ We need to redirect the standard error separately from the standard output ¯ We use the operator 2> to redirect the standard error ¯ To redirect just the standard error: if expr "$1" = "Tony" 2> /dev/null ¯ To redirect both the standard output and the standard error: if expr "$1" = "Tony" > /dev/null 2> /dev/null
6
19 Beware of File Substitution
¯ Remember that the * character will match against any file name ¯ In shell programs, file matching characters still match against files ¯ What if we want to multiply two numbers ¯ The following will return a syntax error: SUM=‘expr $1 * $2‘ ¯ The * will be replace by a list of files, giving the syntax error ¯ We need to put a backslash before the * to make the shell take the next character literally and not to interpret it: SUM=‘expr $1 \* $2‘
7