Advanced UNIX

99
40-491 Adv. UNIX:Bourne/6 Advanced UNIX Advanced UNIX Objectives Objectives explain how to write Bourne explain how to write Bourne and Bash Shell scripts and Bash Shell scripts 240-491 Special Topics in Comp. Eng. 1 Semester 2, 2000-2001 6. The Bourne and Bash Shells

description

Advanced UNIX. 240-491 Special Topics in Comp. Eng. 1 Semester 2, 2000-2001. Objectives explain how to write Bourne and Bash Shell scripts. 6. The Bourne and Bash Shells. Overview. 1. Making a File Executable 2. Combining Commands 3. Redirecting Output 4. Executing Scripts - PowerPoint PPT Presentation

Transcript of Advanced UNIX

Page 1: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 1

Advanced UNIXAdvanced UNIX

ObjectivesObjectives– explain how to write Bourne and Bash explain how to write Bourne and Bash

Shell scriptsShell scripts

240-491 Special Topics in Comp. Eng. 1Semester 2, 2000-2001

6. The Bourne and Bash Shells

Page 2: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 2

OverviewOverview

1. 1. Making a File ExecutableMaking a File Executable

2. 2. Combining CommandsCombining Commands

3. 3. Redirecting OutputRedirecting Output

4. 4. Executing ScriptsExecuting Scripts

5. 5. VariablesVariables

6. 6. Control FlowControl Flow

continued

Page 3: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 3

7.7. FunctionsFunctions

8.8. Other CommandsOther Commands

9.9. Here DocumentsHere Documents

10.10. DebuggingDebugging

11.11. More InformationMore Information

Page 4: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 4

1. Making a File Executable1. Making a File Executable

$ cat whoson$ cat whosondatedateecho Users currently logged onecho Users currently logged onwhowho

Wrong:Wrong:$ whoson$ whosonwhoson: Permission deniedwhoson: Permission denied

Page 5: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 5

Right:Right: $ ls -lg whoson$ ls -lg whoson-rw-r--r-- 1 ad pubs 42 Jun 17 10:55 whoson-rw-r--r-- 1 ad pubs 42 Jun 17 10:55 whoson$ chmod u+x whoson$ chmod u+x whoson$ ls -lg whoson$ ls -lg whoson-rwxr--r-- 1 ad pubs 42 Jun 17 10:55 whoson-rwxr--r-- 1 ad pubs 42 Jun 17 10:55 whoson

$ whoson$ whosonTue Nov 7 13:21:34 ICT 2000Tue Nov 7 13:21:34 ICT 2000Users currently logged inUsers currently logged inad consol Nov 7 08:26ad consol Nov 7 08:26jenny tty02 Nov 7 10:04jenny tty02 Nov 7 10:04

Page 6: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 6

Possible Possible PATHPATH ProblemProblem

$ whoson$ whosonwhoson: Command not foundwhoson: Command not found

Due to Due to PATHPATH shell variable (see later)shell variable (see later)

Quick fixes:Quick fixes:$ ./whoson$ ./whoson

oror $ sh whoson$ sh whoson

Page 7: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 7

2. Combining Commands2. Combining Commands

Sequencing:Sequencing:$ a ; b ; c $ a ; b ; c

same as:same as:$ a$ a$ b$ b$ c$ c

Page 8: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 8

Process Creation (&)Process Creation (&) $ a & b & c$ a & b & c1427114271 (PID for a)(PID for a)1427214272 (PID for b)(PID for b)

$ a & b & c &$ a & b & c &142901429014291142911429214292$$

$ a | b | c &$ a | b | c &1430214302 (PID for piped commands)(PID for piped commands)

Page 9: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 9

Processes in ActionProcesses in Action

$ cat a$ cat aecho -n “aaaaaaaaaaaaaaaaaaaaa”echo -n “aaaaaaaaaaaaaaaaaaaaa”echo -n “aaaaaaaaaaaaaaaaaaaaa”echo -n “aaaaaaaaaaaaaaaaaaaaa”sleep 2sleep 2echo -n “aaaaaaaaaaaaaaaaaaaaa”echo -n “aaaaaaaaaaaaaaaaaaaaa”echo -n “aaaaaaaaaaaaaaaaaaaaa”echo -n “aaaaaaaaaaaaaaaaaaaaa”

Similarly for b and cSimilarly for b and c

Try the following a few times:Try the following a few times:$ a & b & c &$ a & b & c &

On calvin thereisn't muchvariation unlessthe machine isloaded.

Page 10: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 10

3. Redirecting Output3. Redirecting Output

1>1> redirect standard output (stdout)redirect standard output (stdout)2>2> redirect standard error (stderr)redirect standard error (stderr)

$ cat a b 1> out 2> err$ cat a b 1> out 2> err

cat a b

out

err

stdout

stderr

Files

Page 11: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 11

>&>&

redirect one stream into another:redirect one stream into another:– 2>&12>&1 redirect stderr into stdoutredirect stderr into stdout

$ cat a b 1> theLot 2>&1$ cat a b 1> theLot 2>&1

cat a b

theLot

stderr

stdout

Page 12: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 12

4. Executing Scripts4. Executing Scripts

Make sure that a script is executed by the Make sure that a script is executed by the Bourne Shell:Bourne Shell:

$ sh whoson$ sh whoson (no need for (no need for chmodchmod))

or:or:$ cat boss$ cat boss#!/bin/sh#!/bin/shecho Definitely Bourne Shell Scriptecho Definitely Bourne Shell Script

continued

Page 13: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 13

On Linux machines (e.g. On Linux machines (e.g. calvincalvin), the ), the Bourne shell has been replaced by BashBourne shell has been replaced by Bash– shsh means the Bash shell means the Bash shell

Page 14: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 14

5. Variables5. Variables

5.1. 5.1. User-defined VariablesUser-defined Variables

5.2. 5.2. Environment VariablesEnvironment Variables

5.3. 5.3. Readonly Shell VariablesReadonly Shell Variables

Page 15: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 15

5.1. User-defined Variables5.1. User-defined Variables

$ person=alex$ person=alex$ echo person$ echo personpersonperson$ echo $ echo $$personpersonalexalex

$var$var returns the value stored in returns the value stored in varvar– called called substitutionsubstitution

No spaces around the =

Page 16: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 16

5.1.1. Switch off Substitution5.1.1. Switch off Substitution

Swich off substitution with Swich off substitution with ''varvar'' or or \var\var

$ echo '$person'$ echo '$person'$person$person$ echo \$person$ echo \$person$person$person

Page 17: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 17

5.1.2. Switch off Special Chars (")5.1.2. Switch off Special Chars (")

"" switches off the special meaning of characters used in "" switches off the special meaning of characters used in filename generation (e.g. *, ?)filename generation (e.g. *, ?)

$ ls$ ls // directory contents// directory contentsad.reportad.reportad.summaryad.summary

$ memo=ad*$ memo=ad*$ echo "$memo"$ echo "$memo"ad*ad*$ echo $memo$ echo $memoad.report ad.summaryad.report ad.summary

* means only *

* means any numberof characters

Page 18: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 18

5.1.3. Exporting Variables5.1.3. Exporting Variables

Normally a variable is local to the running script Normally a variable is local to the running script (the process).(the process).

It is sometimes useful if running scripts It is sometimes useful if running scripts (processes) can access another script’s variables.(processes) can access another script’s variables.

e.g.e.g.

extest subtest

cheese=english

callswe want touse cheesein subtest

Page 19: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 19

No Exporting: No Exporting: extest1extest1 & & subtestsubtest

$ cat extest1$ cat extest1cheese=englishcheese=englishecho "extest1 1: $cheese"echo "extest1 1: $cheese"subtestsubtestecho "extest1 2: $cheese"echo "extest1 2: $cheese"

$cat subtest$cat subtestecho "subtest 1: $cheese"echo "subtest 1: $cheese"cheese=swisscheese=swissecho "subtest 2: $cheese"echo "subtest 2: $cheese"

continued

Using " isa good habit,see later

Page 20: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 20

$ extest1$ extest1extest1 1: englishextest1 1: englishsubtest 1: subtest 1: subtest 2: swisssubtest 2: swissextest1 2: englishextest1 2: english

subtest does notsee extest1's cheese value

extest1 is not affectedby subtest's setting ofcheese

Page 21: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 21

Exporting: Exporting: extest2extest2 & & subtestsubtest

$ cat extest2$ cat extest2exportexport cheese cheesecheese=englishcheese=englishecho “extest2 1: $cheese”echo “extest2 1: $cheese”subtestsubtestecho “extest2 2: $cheese”echo “extest2 2: $cheese”

$ extest2$ extest2extest2 1: englishextest2 1: englishsubtest 1: englishsubtest 1: englishsubtest 2: swisssubtest 2: swissextest2 2: english extest2 2: english

cheese value passed in

change not exportedfrom subtest

Page 22: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 22

5.1.4. Reading5.1.4. Reading

$ cat readln$ cat readlnecho -n “Type: ”echo -n “Type: ”readread ln lnecho “You entered: $ln”echo “You entered: $ln”

$ readln$ readlnType: Type: The Wizard of OzThe Wizard of OzYou entered: The Wizard of OzYou entered: The Wizard of Oz

read inputs everythingup to the newline

Page 23: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 23

No QuotesNo Quotes

$ cat readlnnq$ cat readlnnqecho -n “Type: ”echo -n “Type: ”read lnread lnecho You entered: $lnecho You entered: $ln

$ ls$ lsad.report summary1ad.report summary1$ readlnnq$ readlnnqType: Type: **You entered: ad.report summary1You entered: ad.report summary1

directorycontents

Page 24: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 24

5.1.5. Executing Commands5.1.5. Executing Commands

$ cat proc_cmd$ cat proc_cmdecho -n “Enter a command: ”echo -n “Enter a command: ”read commandread command$command$commandecho Thanksecho Thanks

$ proc_cmd$ proc_cmdEnter a command: Enter a command: echo Display thisecho Display thisDisplay thisDisplay thisThanksThanks

A very simple shell

Page 25: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 25

5.1.6. Splitting Input5.1.6. Splitting Input

$ cat split3$ cat split3echo -n “Enter something: ”echo -n “Enter something: ”read read word1 word2 word3word1 word2 word3echo “Word 1 is: $word1”echo “Word 1 is: $word1”echo “Word 2 is: $word2”echo “Word 2 is: $word2”echo “Word 3 is: $word3”echo “Word 3 is: $word3”

$ split3$ split3Enter something: Enter something: this is somethingthis is somethingWord1 is: thisWord1 is: thisWord2 is: isWord2 is: isWord3 is: somethingWord3 is: something

Text is splitbased on whitespace.

Page 26: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 26

$ split3$ split3Enter something: Enter something: this is something else, xthis is something else, xWord1 is: thisWord1 is: thisWord2 is: isWord2 is: isWord3 is: something else, xWord3 is: something else, x

The last variable getseverything that is leftin the input.

Page 27: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 27

5.1.7. Command Subsitution5.1.7. Command Subsitution

$ cat mydir$ cat mydirthis_dir=‘pwd‘this_dir=‘pwd‘echo “Using the $this_dir directory.”echo “Using the $this_dir directory.”this_date=$(date)this_date=$(date)echo "Today's date: $this_date"echo "Today's date: $this_date"

$ mydir$ mydirUsing /home/ad/teach/adv-unix/bourne Using /home/ad/teach/adv-unix/bourne directorydirectoryToday's date: Tue Nov 7 13:52:46 ICT 2000Today's date: Tue Nov 7 13:52:46 ICT 2000$ $

A Bashaddition

Must use ‘

Page 28: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 28

5.2. Environment Variables5.2. Environment Variables

Most environment variables get their values from Most environment variables get their values from the shell at login.the shell at login.

The values of The values of somesome of the variables can be set by of the variables can be set by editing the editing the .profile.profile file in your home directory file in your home directory– Bash usesBash uses .bash_profile .bash_profile and and .bashrc.bashrc

Page 29: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 29

5.2.1. Examples5.2.1. Examples

HOMEHOME pathname of your home directorypathname of your home directory

$ pwd$ pwd/home/ad/planning/home/ad/planning$ echo $HOME$ echo $HOME/home/ad/home/ad$ cd$ cd$ pwd$ pwd/home/ad/home/ad

continued

cd uses HOMEto return to yourhome directory

Page 30: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 30

PATHPATH

– directories where executable can be founddirectories where executable can be found– represented as a string of pathnames separated by represented as a string of pathnames separated by ‘:’‘:’ss

$ echo $PATH$ echo $PATH/usr/local/bin:/usr/bin:/bin:/usr/local/bin:/usr/bin:/bin:$ PATH=SPATH":/home/ad/bin:."$ PATH=SPATH":/home/ad/bin:."$ echo $PATH$ echo $PATH/usr/local/bin:/usr/bin:/bin:/home/ad/bin:./usr/local/bin:/usr/bin:/bin:/home/ad/bin:.

Extend thedefault PATH

Page 31: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 31

Note for SysAdminsNote for SysAdmins

If you are the system administrator If you are the system administrator (superuser, root) for your machine, do (superuser, root) for your machine, do notnot extend your path with "."extend your path with "."– it opens you to potential attack by hackersit opens you to potential attack by hackers– e.g. 'fake' UNIX utilities placed in the current e.g. 'fake' UNIX utilities placed in the current

directory directory

Page 32: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 32

5.2.2. Typical .profile5.2.2. Typical .profile

$ cat .profile$ cat .profileTERM=vt100TERM=vt100PATH=$PATH":/home/ad/bin:."PATH=$PATH":/home/ad/bin:."PS1=“ad: “PS1=“ad: “CDPATH=:$HOMECDPATH=:$HOMEexport TERM PATH PS1 CDPATHexport TERM PATH PS1 CDPATH

stty kill ^ustty kill ^u

$ . .profile$ . .profileexport neededin the Bourne shell

Page 33: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 33

5.2.3. Typical .bash_profile5.2.3. Typical .bash_profile

On On calvincalvin, , .bash_profile.bash_profile simply invokes simply invokes your your .bashrc.bashrc (if it exists): (if it exists):

umask 002umask 002if [ -f ~/.bashrc -a PS1="\$ " ]; thenif [ -f ~/.bashrc -a PS1="\$ " ]; then . ~/.bashrc . ~/.bashrcfifi

continued

These shell commandswill be explained later

Page 34: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 34

Typical .bashrcTypical .bashrc

PS1="\u@\h$ "PS1="\u@\h$ "# PS1="\w[\#]$ "# PS1="\w[\#]$ "PATH=$PATH":."PATH=$PATH":."

alias ls='/bin/ls -F'alias ls='/bin/ls -F'alias dir='ls -ba'alias dir='ls -ba'alias cls="clear"alias cls="clear"

::::

psgrep()psgrep(){{ ps aux | grep ps aux | grep $1$1 | grep -v grep | grep -v grep}}

These featureswill be explainedlater.

No export needed

Page 35: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 35

5.2.4. set5.2.4. set

The current settings for the environment The current settings for the environment variables can be listed with variables can be listed with setset::

$ set | more$ set | moreBASH=/bin/bashBASH=/bin/bash

::PATH=/usr/local/bin:/usr/bin:/bin:.PATH=/usr/local/bin:/usr/bin:/bin:.

::PS1='\u@\h$ 'PS1='\u@\h$ '

::

Page 36: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 36

5.3. Readonly Shell Variables5.3. Readonly Shell Variables

These are environment variables that These are environment variables that cannotcannot have their values changed. have their values changed.

Most of them relate to the arguments Most of them relate to the arguments supplied to a script when it is called.supplied to a script when it is called.

Page 37: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 37

5.3.1. Script Name (5.3.1. Script Name ($0$0))

$ cat abc$ cat abcecho The name of this script is echo The name of this script is $0$0

$ abc$ abcThe name of this script is The name of this script is abcabc

Page 38: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 38

5.3.2. Script Arguments (5.3.2. Script Arguments ($1, $2,..., $9$1, $2,..., $9))

$ cat display_5args$ cat display_5argsecho The first five command lineecho The first five command lineecho arguments are echo arguments are $1 $2 $3 $4 $5$1 $2 $3 $4 $5

$ display_5args jenny alex helen$ display_5args jenny alex helenThe first five command lineThe first five command linearguments are arguments are jenny alex helenjenny alex helen

If the variable has no value, then nothing is printed.

Page 39: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 39

5.3.3. All Arguments (5.3.3. All Arguments ($*$*))

$ cat display_all$ cat display_allecho echo $*$*

$ display_all a b c de fg hi jk mno pqr $ display_all a b c de fg hi jk mno pqr stu w x y zstu w x y z

a b c de fg hi jk mno pqr stu w x y za b c de fg hi jk mno pqr stu w x y z

$@$@ is like is like $*$* but puts “...” around each but puts “...” around each printed argumentprinted argument

Page 40: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 40

5.3.4. Number of Arguments (5.3.4. Number of Arguments ($#$#))

$ cat num_args$ cat num_argsecho “This script has echo “This script has $#$# arguments.” arguments.”

num_args helen alex jennynum_args helen alex jennyThis script has This script has 33 arguments arguments

Page 41: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 41

5.3.5. The 5.3.5. The shiftshift CommndCommnd

shiftshift moves argument values on the moves argument values on the command line one command line one $<number>$<number> to the left. to the left.

Overcomes limit of 9 argument variablesOvercomes limit of 9 argument variables(($1, $2, ..., $9$1, $2, ..., $9))

continued

Page 42: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 42

$ cat demo_shift$ cat demo_shiftecho “arg1= $1 arg2= $2 arg3= $3”echo “arg1= $1 arg2= $2 arg3= $3”shiftshiftecho “arg1= $1 arg2= $2 arg3= $3”echo “arg1= $1 arg2= $2 arg3= $3”shiftshiftecho “arg1= $1 arg2= $2 arg3= $3”echo “arg1= $1 arg2= $2 arg3= $3”shiftshift

$ demo_shift alice helen jenny june$ demo_shift alice helen jenny junearg1= alice arg2= helen arg3= jennyarg1= alice arg2= helen arg3= jennyarg1= helen arg2= jenny arg3= june arg1= helen arg2= jenny arg3= june arg1= jenny arg2= june arg3=arg1= jenny arg2= june arg3=

jenny "moves"to the left.

Page 43: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 43

5.3.6. The 5.3.6. The setset Command (Again)Command (Again)

set ‘cmd‘set ‘cmd‘ (must use (must use ‘‘))

– evaluates evaluates cmdcmd and assigns its values to the script and assigns its values to the script command line arguments (command line arguments ($1, $2, ..., $1, $2, ..., $9, $*$9, $*))

– the values in the values in cmdcmd output are separated by output are separated by whitespacewhitespace

continued

Page 44: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 44

$ date$ dateFri Jun 17 23:04:09 GMT+7 1996Fri Jun 17 23:04:09 GMT+7 1996$ cat dateset$ cat datesetset ‘date‘set ‘date‘echo $*echo $*echoechoecho “Argument 1: $1”echo “Argument 1: $1”echo “Argument 2: $2”echo “Argument 2: $2”echo “Argument 3: $3”echo “Argument 3: $3”echo $2 $3, $6echo $2 $3, $6

continued

The date valuesare assigned to $1,$2, etc.

Page 45: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 45

$ dataset$ datasetFri Jun 17 23:04:13 GMT+7 1996Fri Jun 17 23:04:13 GMT+7 1996

Argument 1: FriArgument 1: FriArgument 2: JunArgument 2: JunArgument 3: 17Argument 3: 17Jun 17, 1996Jun 17, 1996

Page 46: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 46

6. Command Flow6. Command Flow

6.1. 6.1. BranchingBranching

6.2. 6.2. Test FormsTest Forms

6.3. 6.3. LoopingLooping

6.4.6.4. breakbreak, , continuecontinue, , ::

6.5. 6.5. traptrap

Page 47: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 47

6.1. Branching6.1. Branching

$ cat same_word$ cat same_wordecho -n “word 1: ”echo -n “word 1: ”read word1read word1echo -n “word 2: ”echo -n “word 2: ”read word2read word2if test "$word1" = "$word2"if test "$word1" = "$word2"thenthen echo Match echo Matchfifiecho End of Programecho End of Program

Use " to stopfilename expansion

continued

Page 48: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 48

$ same_word$ same_wordword1: peachword1: peachword2: peachword2: peachMatchMatchEnd of ProgramEnd of Program

Page 49: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 49

$ cat chkargs$ cat chkargsif [ $# = 0 ]if [ $# = 0 ]thenthen echo Usage: chkargs argument... 1>&2 echo Usage: chkargs argument... 1>&2 exit 1 exit 1fifiecho Program runningecho Program runningexit 0exit 0

$ chkargs$ chkargsUsage: chkargs argument...Usage: chkargs argument...$ chkargs abc$ chkargs abcProgram runningProgram running

Redirectstdout to stderr

6.1.1. Second Format6.1.1. Second Format

Page 50: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 50

6.1.2. if-then-else6.1.2. if-then-else $ cat show$ cat showif [ $# = 0 ]if [ $# = 0 ];; then then echo Usage: show [-v] filenames 1>&2 echo Usage: show [-v] filenames 1>&2 exit 1 exit 1fifiif [ “$1” != “-v” ]if [ “$1” != “-v” ]thenthen cat “$@” cat “$@”elseelse shift shift more “$@” more “$@”fifi

C programmersprefer this format

Use: $ show -v f1.txt f2.txt

Page 51: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 51

6.1.3. if-then-elif6.1.3. if-then-elif

$ cat same3$ cat same3echo -n “word 1: ”echo -n “word 1: ”read word1read word1echo -n “word 2: ”echo -n “word 2: ”read word2read word2echo -n “word 3: ”echo -n “word 3: ”read word3read word3if [ “$word1” = “$word2” if [ “$word1” = “$word2” -a \-a \

“$word2” = “$word3” ]“$word2” = “$word3” ]thenthen echo “Match: words 1, 2, and 3” echo “Match: words 1, 2, and 3”

continued

For multiway branches

-a means "and"\ means "continuedon next line"

Page 52: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 52

elifelif [ “$word1” = “$word2” ] [ “$word1” = “$word2” ]thenthen echo “Match: words 1 and 2” echo “Match: words 1 and 2”elif [ “$word1” = “$word3” ]elif [ “$word1” = “$word3” ]thenthen echo “Match: words 1 and 3” echo “Match: words 1 and 3”elif [ “$word2” = “$word3” ]elif [ “$word2” = “$word3” ]thenthen echo “Match: words 2 and 3” echo “Match: words 2 and 3”elseelse echo “No match” echo “No match”fifi

Page 53: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 53

6.1.4. case6.1.4. case

$cat command_menu$cat command_menu#!/bin/sh#!/bin/sh# menu interface to simple commands# menu interface to simple commands

echo “\n COMMAND MENU\n”echo “\n COMMAND MENU\n”echo “ a. Current date and time”echo “ a. Current date and time”echo “ b. Users currently logged in”echo “ b. Users currently logged in”echo “ c. Name of working directory”echo “ c. Name of working directory”echo “ d. Contents of working directory”echo “ d. Contents of working directory”echo -n “Enter a, b, c, or d: ”echo -n “Enter a, b, c, or d: ”read answerread answerechoecho

continued

Better style: specifythe shell, and commentthe code.

Page 54: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 54

casecase “$answer” in “$answer” in a) date a) date ;; ;; b) who b) who ;; ;; c) pwd c) pwd ;; ;; d) ls -C d) ls -C ;; ;; *) echo “$answer not legal” *) echo “$answer not legal” ;; ;;esacesacechoecho

* is the default;always include itat the end

Page 55: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 55

$ command_menu$ command_menu COMMAND MENU COMMAND MENU

a. Current date and time a. Current date and time b. Users currently logged in b. Users currently logged in c. Name of working directory c. Name of working directory d. Contents of working directory d. Contents of working directoryEnter a, b, c, or d: Enter a, b, c, or d: aa

Fri Jun 17 14:11:57 GMT 1996Fri Jun 17 14:11:57 GMT 1996

Page 56: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 56

Other case PatternsOther case Patterns

?? matches a single charactermatches a single character

[...][...] any character in the brackets.any character in the brackets.Use - to specify a range (e.g. Use - to specify a range (e.g. a-za-z))

|| or (e.g. or (e.g. a|Aa|A))

** it can be used to match "any it can be used to match "any number of characters"number of characters"

Page 57: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 57

$cat timeDay$cat timeDay#!/bin/sh#!/bin/shecho Is it morning? Answer yes or noecho Is it morning? Answer yes or noread timeofdayread timeofday

case "$timeofday" incase "$timeofday" in "yes" | "y" | "Yes" | "YES" ) "yes" | "y" | "Yes" | "YES" ) echo "Good Morning" echo "Good Morning"

;; ;; [nN]* ) [nN]* ) echo "Good Afternoon" echo "Good Afternoon" ;; ;; *) echo "Uhh??" *) echo "Uhh??" ;; ;;esacesac

Page 58: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 58

6.2. test Forms6.2. test Forms

Format:Format:test exprtest expr

[ expr ][ expr ]

e.g.e.g.test “$word1” = “$word2”test “$word1” = “$word2”

[ “$1” != “-v” ][ “$1” != “-v” ]

[ “$word2” = “$word3” ][ “$word2” = “$word3” ]

[ “$word1” = “$word2” -a \[ “$word1” = “$word2” -a \“$word2” = “$word3” ]“$word2” = “$word3” ]

Used in the conditions of if's and loops.

Page 59: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 59

6.2.1. String Expressions6.2.1. String Expressions

string1 = string2string1 = string2

string1 != string2string1 != string2

-n string-n string (true if string is (true if string is notnot ““““))

-z string-z string (true if string is (true if string is ““)““)

Page 60: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 60

6.2.2. Numerical Expressions6.2.2. Numerical Expressions

number1 -eq number2number1 -eq number2 (equality)(equality) number1 -ne number2number1 -ne number2 (inequality)(inequality)

number1 -lt number2number1 -lt number2 (<)(<) number1 -le number2number1 -le number2 (<=)(<=)

number1 -gt number2number1 -gt number2 (>)(>) number1 -ge number2number1 -ge number2 (>=)(>=)

Page 61: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 61

6.2.4. File Test Expressions6.2.4. File Test Expressions

-f file-f file (file exists)(file exists) -d file-d file (file exists but is a (file exists but is a

directory)directory)

-r file-r file (file is readable)(file is readable) -w file-w file (file is writable)(file is writable) -x file-x file (file is executable)(file is executable)

Page 62: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 62

6.2.5. Combining Expressions6.2.5. Combining Expressions

! expr! expr (not expr)(not expr)

expr1 -a expr2expr1 -a expr2 (and)(and)– Bash allows Bash allows &&&& as well as well

expr1 -o expr2expr1 -o expr2 (or)(or)– Bash allows Bash allows |||| as well as well

( expr )( expr )

Page 63: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 63

6.3. Looping (for-in)6.3. Looping (for-in)

Format:Format:

forfor loop-index loop-index inin argument-list argument-listdodo commands commandsdonedone

Page 64: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 64

$ cat fruit$ cat fruitfor fruit in apples oranges pearsfor fruit in apples oranges pearsdodo echo $fruit echo $fruitdonedoneecho Task completedecho Task completed

$ fruit$ fruitapplesapplesorangesorangespearspearsTask completedTask completed

Page 65: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 65

Looking for “for” in filesLooking for “for” in files

First version of script:First version of script:

$ car file-fors1$ car file-fors1for f in ‘ls‘for f in ‘ls‘dodo echo $f echo $fdonedone

Page 66: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 66

$ cat file-fors2$ cat file-fors2for f in ‘ls‘for f in ‘ls‘dodo grep -i “for” $f > /dev/null grep -i “for” $f > /dev/null if [ $? == 0 ] if [ $? == 0 ] then then echo $f echo $f fi fidonedone

Ignore output

Page 67: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 67

6.3.1. for 6.3.1. for $ cat whos$ cat whos# Give user details from /etc/passwd# Give user details from /etc/passwdif [ $# = 0 ]if [ $# = 0 ]thenthen echo Usage: whos id... 1>&2 echo Usage: whos id... 1>&2 exit 1 exit 1fifi

forfor i i # read as # read as for i in “$@”for i in “$@”dodo awk -F: awk -F: ’’{print $1, $5}{print $1, $5}’’ /etc/passwd /etc/passwd || grep -i “$i”grep -i “$i”donedone

awk variableswith ’

Page 68: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 68

6.3.2. while6.3.2. while $ cat count$ cat countnumber=0number=0while [ $number -lt 10 ]while [ $number -lt 10 ]dodo echo -n "$number" echo -n "$number" number=‘expr $number + 1‘ number=‘expr $number + 1‘donedoneechoecho

$ count$ count01234567890123456789$$

Page 69: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 69

Watching for Mary to log inWatching for Mary to log in

while sleep 60while sleep 60dodo who | grep mary who | grep marydonedone

Disadvantages:Disadvantages:– if Mary is already logged in, then we must if Mary is already logged in, then we must

wait 60 secs to find outwait 60 secs to find out– we keep being told that Mary is logged inwe keep being told that Mary is logged in

Page 70: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 70

6.3.3. until6.3.3. until Format:Format:

until commanduntil commanddodo loop body until loop body until the command evaluates to true the command evaluates to truedonedone

Watching (v.2):Watching (v.2):until who | grep maryuntil who | grep marydodo sleep 60 sleep 60donedone loop until grep

returns ‘true’ (0)

Page 71: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 71

6.3.4. Extending Watching6.3.4. Extending Watching

Generalise so can watch for anyone:Generalise so can watch for anyone:$ watchfor ad$ watchfor ad

Watch for everyone logging in/out:Watch for everyone logging in/out:$ watchwho$ watchwho

Page 72: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 72

watchforwatchfor#!/bin/sh#!/bin/sh# watchfor# watchfor# watch for person supplied as argument# watch for person supplied as argument

if [ $# = 0 ]if [ $# = 0 ]thenthen echo “Usage: watchfor person” echo “Usage: watchfor person” exit 1 exit 1fifiuntil who | grep “$1”until who | grep “$1”dodo sleep 60 sleep 60donedone

Page 73: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 73

watchwhowatchwho

Once a minute, run Once a minute, run whowho and compare its output and compare its output to that from a minute ago. Report any to that from a minute ago. Report any differences.differences.

Keep the Keep the whowho output in files in output in files in /tmp/tmp

Give the files unique names by adding the shell Give the files unique names by adding the shell variable variable $$$$..– $$$$ is the PID of the user’s shell is the PID of the user’s shell

Page 74: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 74

#!/bin/sh#!/bin/sh# watchwho: watch who logs in and out# watchwho: watch who logs in and out

new=/tmp/wwho1.$$new=/tmp/wwho1.$$old=/tmp/wwho2.$$old=/tmp/wwho2.$$> $old # create an empty file> $old # create an empty file

while truewhile truedodo who > $new who > $new diff $old $new diff $old $new mv $new $old mv $new $old sleep 60 sleep 60done done || awk ’/>/ {$1 = “in: “; print} awk ’/>/ {$1 = “in: “; print}

/</ {$1 = “out: “; print}’ /</ {$1 = “out: “; print}’

An advancedShell programmingtechnique: |

Page 75: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 75

UseUse $ watchwho$ watchwho

in: root tty1 Nov 6 09:32in: root tty1 Nov 6 09:32in: ad pts/3 Nov 8 08:49 (myrrh.coe.psu.ac.th)in: ad pts/3 Nov 8 08:49 (myrrh.coe.psu.ac.th)in: s4010441 pts/5 Nov 8 10:11 (192.168.0.134)in: s4010441 pts/5 Nov 8 10:11 (192.168.0.134)in: ad pts/4 Nov 8 10:12 (myrrh.coe.psu.ac.th)in: ad pts/4 Nov 8 10:12 (myrrh.coe.psu.ac.th)in: s4010143 pts/17 Nov 7 23:57 (192.168.0.204)in: s4010143 pts/17 Nov 7 23:57 (192.168.0.204)out: ad pts/4 Nov 8 10:12 (myrrh.coe.psu.ac.th)out: ad pts/4 Nov 8 10:12 (myrrh.coe.psu.ac.th)in: ad pts/4 Nov 8 10:16 (myrrh.coe.psu.ac.th)in: ad pts/4 Nov 8 10:16 (myrrh.coe.psu.ac.th)out: ad pts/4 Nov 8 10:18 (myrrh.coe.psu.ac.th)out: ad pts/4 Nov 8 10:18 (myrrh.coe.psu.ac.th)

::

initialusers

Page 76: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 76

NotesNotes diffdiff uses ‘uses ‘<<‘ and ‘‘ and ‘>>‘ to distinguish data ‘ to distinguish data

from from $old$old and and $new$new

$ diff old new$ diff old new< ad< ad> mary> mary

johnad

old

johnmary

new

continued

Page 77: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 77

The output from the The output from the whilewhile loop is piped into loop is piped into awkawk– only one call to only one call to awkawk is required is required– the "pipe" programming stylethe "pipe" programming style

A A calvincalvin problem: problem:– awkawk had to be called with the had to be called with the -W interactive-W interactive option so that its output was not buffered option so that its output was not buffered– otherwise nothing would appearotherwise nothing would appear

whileloop

awk

Page 78: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 78

6.3.5. Checking mail6.3.5. Checking mail

Have a script watch your mailbox Have a script watch your mailbox periodically, and report whenever the periodically, and report whenever the mailbox changes by printing mailbox changes by printing ““You have You have

mailmail””..

Usage:Usage:– $ checkmail$ checkmail # checks every 60 secs# checks every 60 secs– $ checkmail 120$ checkmail 120 # checks every 120 secs# checks every 120 secs

Page 79: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 79

checkmailcheckmail

#!/bin/sh#!/bin/sh# checkmail: watch mailbox for growth# checkmail: watch mailbox for growth

time=${1-60}time=${1-60}

oldls="‘ls -l $MAIL‘"oldls="‘ls -l $MAIL‘"while truewhile truedodo newls="‘ls -l $MAIL‘" newls="‘ls -l $MAIL‘" echo $oldls $newls echo $oldls $newls oldls="$newls" oldls="$newls" sleep $time sleep $timedone done || awk ’$5 < $14 {print “You have mail”}’ awk ’$5 < $14 {print “You have mail”}’

uses the pipe technique

Page 80: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 80

NotesNotes

$$MAILMAIL is a builtin shell variable, with the is a builtin shell variable, with the value value /var/spool/mail/$USER/var/spool/mail/$USER

t=${1-60}t=${1-60} sets sets tt to to $1$1 or, if no argument is or, if no argument is provided, to provided, to 6060– General form: General form: ${var-thing}${var-thing}

returns value of returns value of varvar if defined; otherwise if defined; otherwise thingthing

continued

Page 81: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 81

Use Use awkawk to print a message only when the to print a message only when the mailbox gets bigger:mailbox gets bigger:– awk $5 $14awk $5 $14 compares the size fields of the compares the size fields of the twotwo ls -lls -l

calls output at the end of each iterationcalls output at the end of each iteration

e.g. e.g. $ ls -l foo$ ls -l foo-rw-r--r-- 1 ad ad 34512 Nov 13 1996 foo-rw-r--r-- 1 ad ad 34512 Nov 13 1996 foo$ ls -l foo$ ls -l foo-rw-r--r-- 1 ad ad 34512 Nov 13 1996 foo-rw-r--r-- 1 ad ad 34512 Nov 13 1996 foo

5th value

14th value

Page 82: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 82

6.4. break, continue, : 6.4. break, continue, :

breakbreak and and continuecontinue are used as in C: are used as in C:– breakbreak escapes from a loop escapes from a loop

for file in fred*for file in fred*dodo if [ -d "$file" ]; then # deleted? if [ -d "$file" ]; then # deleted? break break # finish loop# finish loop fi fi # do something # do something # #donedone

continued

Page 83: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 83

continuecontinue goes to the top of a loop: goes to the top of a loop:

for file in fred*for file in fred*dodo if [ -d "$file" ]; then # deleted? if [ -d "$file" ]; then # deleted? continue continue # go back to loop # go back to loop toptop fi fi # do something # do something # #donedone

continued

Page 84: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 84

The The ':'':' command is the same as command is the same as truetrue, but , but runs a runs a tinytiny bit faster bit faster– often used to simplify control logicoften used to simplify control logic

if [ -f fred ]; then # is fred a file?if [ -f fred ]; then # is fred a file? : # do nothing : # do nothingelseelse # do something # do something # #fifi

Page 85: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 85

6.5. trap6.5. trap

Capture user interrupts or system call failures.Capture user interrupts or system call failures.

Format (with Format (with ’)’)::trap ’commands’ signal-numbers-or-nametrap ’commands’ signal-numbers-or-name

Some signal numbers (names):Some signal numbers (names):– 2 (2 (INTINT)) press delete or control-Cpress delete or control-C– 3 (3 (QUITQUIT)) press control-| or control-\press control-| or control-\– 15 (15 (TERMTERM)) kill command signalkill command signal

continued

Page 86: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 86

A complete A complete list of available signalslist of available signals is given is given by typing by typing trap -ltrap -l at the command line. at the command line.

To To ignoreignore a signal, set the a signal, set the traptrap command to command to be empty (be empty (’’’’) )

To To resetreset signal processing, set the command signal processing, set the command to to --

continued

Page 87: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 87

$ cat inter$ cat inter

trap trap ’’echo PROGRAM INTERRUPTED; exit 1echo PROGRAM INTERRUPTED; exit 1’’ INT INTwhile truewhile truedodo echo Program running. echo Program running. sleep 2 sleep 2donedone

Page 88: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 88

7. Functions7. Functions

Bash allows shell scripts to use functions:Bash allows shell scripts to use functions:function_name() {function_name() { statements statements}}

Functions must be defined textually before Functions must be defined textually before they are used.they are used.

continued

Page 89: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 89

Functions can Functions can returnreturn integer values integer values

Function parameters are passed by modifying Function parameters are passed by modifying $*$*, , $@$@, , $#$#, , $1$1 -- -- $9$9 while the function is executing. while the function is executing.

Local variables are defined with the Local variables are defined with the locallocal keywordkeyword– the other variables in a script are global by defaultthe other variables in a script are global by default

Page 90: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 90

my_namemy_name #!/bin/sh#!/bin/sh

yes_or_no() {yes_or_no() { # a function# a function echo "Is your name echo "Is your name $*$* ?" ?" while true while true do do echo -n "Enter yes or no: " echo -n "Enter yes or no: " read x read x case "$x" in case "$x" in y | yes ) y | yes ) return 0return 0;;;; n | no ) n | no ) return 1return 1;;;; * ) echo "Answer yes or no" * ) echo "Answer yes or no" esac esac done done} # end of yes_or_no()} # end of yes_or_no()

continued

Page 91: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 91

# the main part of the script# the main part of the script

echo "Original parameters are echo "Original parameters are $*$*""

if yes_or_no "if yes_or_no "$1$1""thenthen echo "Hi echo "Hi $1$1, nice name", nice name"elseelse echo "Never mind" echo "Never mind"fifi

exit 0exit 0

Page 92: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 92

UseUse

$ my_name andrew davison$ my_name andrew davisonOriginal parameters are andrew davisonOriginal parameters are andrew davisonIs your name andrew ?Is your name andrew ?Enter yes or no: Enter yes or no: yyHi andrew, nice nameHi andrew, nice name$ $

Page 93: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 93

8. Useful Scripting Commands8. Useful Scripting Commands

exprexpr evaluates its argument as an expression: evaluates its argument as an expression:ans=‘expr $x + 1‘ans=‘expr $x + 1‘

The usually operators are available:The usually operators are available:– + - * / (integer divison) % (modulo)+ - * / (integer divison) % (modulo)– > >= < <=> >= < <=– = (equality) !== (equality) !=– | (or) & (and)| (or) & (and)

continued

Page 94: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 94

Bash supports Bash supports printfprintf, as a more flexible , as a more flexible echoecho– printf "format string" parameter1 ...printf "format string" parameter1 ...

Very similar to Very similar to printf()printf() in C in C– main restriction is no support for floatsmain restriction is no support for floats– only integers are supported in the shellonly integers are supported in the shell

$ printf "%s %d\t%s\n" "hi there" 15 students$ printf "%s %d\t%s\n" "hi there" 15 studentshi there 15 studentshi there 15 students$$

printfprintf

Page 95: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 95

9. Here Documents9. Here Documents

A here document allows input to be passed A here document allows input to be passed into a command from into a command from withinwithin a script a script– the command thinks the input is coming from a the command thinks the input is coming from a

file or input streamfile or input stream

A here document begins with A here document begins with <<LABEL<<LABEL, and , and ends with ends with LABELLABEL

– LABELLABEL can be anything can be anything

Page 96: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 96

$ cat here1$ cat here1#!/bin/sh#!/bin/sh

cat <<!FUNKY!cat <<!FUNKY!hellohellothis is a herethis is a heredocumentdocument!FUNKY!!FUNKY!

$ here1$ here1hellohellothis is a herethis is a heredocumentdocument$ $

the heredocument

Page 97: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 97

10. Debugging10. Debugging

Various options can be set when invoking a Various options can be set when invoking a shell script to help with debugging.shell script to help with debugging.

There are two ways to set the options:There are two ways to set the options:– from the command linefrom the command line when calling the script when calling the script– from within the script by from within the script by using setusing set

continued

Page 98: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 98

Command LineCommand Line SetSet sh -n scriptsh -n script set -nset -n

– do not execute the script, only parse itdo not execute the script, only parse it

sh -v scriptsh -v script set -vset -v

– echoes commands after executing themechoes commands after executing them

sh -x scriptsh -x script set -uset -u

– warns when an undefined variable is used warns when an undefined variable is used

Page 99: Advanced UNIX

240-491 Adv. UNIX:Bourne/6 99

11. More Information11. More Information

The Bourne Shell:The Bourne Shell:– Ch. 10, SobellCh. 10, Sobell

Bourne/Bash:Bourne/Bash:– Beginning Linux ProgrammingBeginning Linux Programming

Neil Matthew and Rick StonesNeil Matthew and Rick StonesChapter 2Chapter 2