shell scripts 4 a shell usually interprets a single line of input, but we can also create a file...

39
Shell Scripts A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted This file is a program known as a shell script The program can also contain control structures (if-then, loops) Shell scripts allow a sequence of commands to be executed automatically (e.g. installation of a program - see /user_client/sybase/install)

Post on 22-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Shell Scripts

A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted– This file is a program known as a shell script– The program can also contain control structures

(if-then, loops)– Shell scripts allow a sequence of commands to be

executed automatically (e.g. installation of a program - see /user_client/sybase/install)

Page 2: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

CSH Input Processing

CSH transforms each command before it is executed by applying the following steps:– History substitutions– Alias substitutions– Variable substitutions– Command substitutions– File name expansions

Page 3: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Shell Script Invocation

A shell script may be invoked either explicitly:– csh file [arg…] or sh file [arg …]

Or implicitly by giving its name on the command line.– In this case, the file must be made executable

(chmod +rx scriptfile)

The shell script is interpreted by a subshell spawned by the user’s interactive shell

Page 4: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

A Simple Example

#this script consults an on-line telephone database

grep -i $1 $HOME/phonenumbers

To make this script executable, chmod +rx Now it can be run from the command line

A commentA positional parameter

An environment variable

Page 5: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Shell Script Basics

A shell script consists of a sequence of built-in and nonbuilt-in commands separated by ; or NEWLINE

Comments begin with a # Script execution is aborted if a built-in command

fails, goes to next command if a nonbuilt-in command fails.

• Remember - built-in commands (e.g. alias) are part of the shell, nonbuilt-in commands (e.g. ls) are separate executable programs.

Page 6: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Executable Text Files

When the shell executes a nonbuilt-in command (i.e. a file) it first determines what type of file the command is.– Executable binary files have a “magic number”

(a few bytes of code) at the beginning.– If this magic number is not found, the file is an

executable text file.• The first few characters of the file tell which shell

should process the file - #/bin/csh or #/bin/sh

Page 7: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Positional Parameters

Parameters can be passed to the script from the command line.– Inside the script, these parameters may be

referenced by using the positional parameters $0, $1, $2, etc.

– $0 refers to the command name (the name of the shell script)

Page 8: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

CSH Scripts

The CSH scripting language is based on the C language.– The positional parameters can alternatively be

referred to as $argv[1], $argv[2], etc.– $argv[*] is a list of all of the arguments given.– $#argv is the number of arguments given.– $argv[0] is undefined. Why?

Page 9: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Control Flow in CSH Scripts

– Rather than just executing a predetermined sequence of commands, a script can be made flexible by using the control flow constructs available:

• foreach• if• switch• while• goto• break• continue

Page 10: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Control Flow in CSH Scripts

The foreach command is used to execute a list of commands for each component of a list of words:foreach var (wordlist)

commandlist

end

– Each time through the loop the variable var is assigned a word from wordlist, and the command list is executed

Page 11: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The foreach Command

#!/bin/csh

foreach x ( * )

echo Changing mode for $x

chmod +rx $x

end

Consider changing mode only for .exe files.

Page 12: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The if Command

Logical branching is provided by the if command:if (expr ) simple-command

if ( expr ) then

commandlist1

[else

commandlist2]

endif

Page 13: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The if Command

##check and set parameters

if ( $#argv > 2 || $#argv < 1 ) then

echo usage: “$0 [ from-file ] to-file”

exit(1);

else

if ( $#argv == 2 ) then

set from = $argv[1]

set to = $argv[2]

else

set to = $argv[1]

endif

endir

Page 14: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The switch Command

– A multiway alternative is provided by the switch command:

switch ( str )

case pattern1:

commandlist1

breaksw

case pattern2:

commandlist2

breaksw

default:

commandlist

endsw

Page 15: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The switch Command

#!/bin/csh

## append $1 to $2 or standard input to $1

switch ( $#argv )

case 1:

cat >> $argv[1]

breaksw

case 2:

cat >> $argv[2] < $argv[1]

breaksw

default:

echo 'usage: append [ from ] to'

endsw

Page 16: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The while Command

The while command executes commands until an expression evaluates to zero:while ( expr )

commandlist

end

Exampleset i = $#argv

while ($i)

echo $argv[$i]

@ i--

end

Page 17: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Numerical Computations

– Notice the ‘@’ in front of the i-- this allows a variable to take on a numeric value (otherwise script variables are string-valued)@ var = expr

@ var[n] = expr

– Examples:

@ x = $#argv/2

@ argv[$j] = $j + 4

@ x += 3

@ i++

Page 18: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Other Control Flow Constructs

– The goto command (goto word) provides an unconditional branch to a label of the form word:

– The break command provides a means to exit the nearest enclosing while or foreach loop.

– The continue command is similar to the break but transfers control to the next iteration rather than breaking out of the loop.

Page 19: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Expressions

– Expressions in csh are similar to those in C:• Logical operators are the same (!, ||, &&)

• Relational operators are the same with the addition of =~ for string match and !~ for string mismatch

• Binary arithmetic operators are the same

• Bitwise logical operators are the same

• Parentheses are used to affect the order of evaluation

• Logical constants (0 for false, 1 for true) are the same

Page 20: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Expressions

• CSH adds file queries to test the status of a file– -r file (Is readable by the user)

– -x file (Is executable by the user)

– -o file (Is owned by the user)

– -f file (Is an ordinary file)

– -w file (Is writable by the user)

– -e file (Exists)

– -z file (Is of zero size)

– -d file (Is a directory)

• We can test whether a command has succeeded in a logical expression by enclosing the command in braces ({ and }):

if ({ command1 } && { command2 } || { command3 } then

Page 21: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Variables

– There are four kinds of variables:1. Positional parameters (e.g. $1 and $argv[2])

2. Special variables such as noglob and nonomatch

3. Environment variables such as DISPLAY and TERM

4. User-defined variables

– Variables are set using the set or @ command:set dir = $cwd

set list = (a b c d)

@ k = $j + 1

set y = “$list”

A multivalued variable

Value of k is a string

Use doublequotes for a multivalued variable

Page 22: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Variables

To select a portion of a multivalued variable, use $var[ selector ]where selector is an integer index, a range (e.g. 2-4) or all of the values (*).

$#var or ${#var} gives the number of strings in a multivalued variable.

Page 23: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Variable Modifiers

– The value of a variable can be modified before it is used in an expression or command by using a variable modifier at the end of a variable.

:h removes a trailing pathname component

:t removes all leading pathname components

:r removes a file extension (e.g. .xxx)

:e removes the root name, leaving the extension

:gh, :gr, :gt, :ge globally modify all strings of a multivalued variable

:q quotes the substituted words, preventing further substitution

:x is like :q but breaks into words at whitespace

Page 24: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Variable Modifiers

#!/bin/csh

set files = *

foreach file ( $files )

echo $file

if ( $file:e == for ) then

mv $file {$file:r}.f77

endif

end

Page 25: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Special Substitutions

To examine whether a variable is set or not use $?var or ${?var}. The string 1 is substituted is var is set, 0 if it is not.

if ( ! $?term ) then

set term = ‘tset - -m dialup:vt100’

endif

The special variable $$ substitutes the process number of the shell executing the script.

Page 26: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Special Substitutions

#!/bin/csh

## Reminder service using calendar and mail

set tfile = /tmp/remind_$$ ## temporary file

calendar > $tfile ## consult calendar file

if ( ! -z $tfile ) then ## send msg if necessary

cat $tfile | /usr/ucb/mail -s \

"Reminder-calendar" $USER

endif

rm -f $tfile

Page 27: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

Input and Output

The command echo words is used to display zero or more words to the standard output.– To prevent a newline after the last word, use echo -n words.

To read user input, the metavariable $< is used. A line from the standard input is read and returned as the value of the metavariable $< without variable- or file-name substitution.

Page 28: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The Here Document

It is possible to include input that is normally entered interactively inside of a script. This type of input is known as a here document and has the following form:command <<word

zero or more

lines of input

included here

word

Page 29: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The Here Document

## script name: timestamp

## usage: timestamp file

cat >> $1 <<here

********************

RECEIVED by $user on `hostname`

`date`

here

Page 30: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The findcmd Script

#!/bin/csh

## this procedure finds where given command is on search path

## the pathname for the command

## is displayed as soon as it is found

## otherwise a message to the contrary is displayed

## This script simulates the UNIX command "which"

set cmd = $1

foreach dir ( $path )

if ( -e $dir/$cmd ) then

echo FOUND: $dir/$cmd

exit(0)

endif

end

echo $cmd not on $path

Page 31: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The append Script

#!/bin/csh

## append $1 to $2 or standard input to $1

switch ( $#argv )

case 1:

cat >> $argv[1]

breaksw

case 2:

cat >> $argv[2] < $argv[1]

breaksw

default:

echo 'usage: append [ from ] to'

endsw

Page 32: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The clean Script

## csh script: clean

## helps to rm unwanted files from a directory

if ($#argv != 1) then

echo usage: $0 directory; exit(1)

endif

set dir = $1

if (! -d $dir || ! -w $dir ) then

echo $dir not a writable directory

echo usage: $0 directory; exit(1)

endif

chdir $dir

set files = *

Page 33: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The clean Script

foreach file ($files)

if (! -f $file ) then

continue ## treat only ordinary files

endif

echo " " ## gives a blank line

/bin/ls -l $file

while (1) ## infinite loop

echo -n "***** Delete $file or not?? [y, n, m, t, ! or q]" :

set c = $< ## obtain user input

switch ( $c )

case y: ## yes -- remove file

if (! -w $file) then

echo $file write-protected

else

rm -f $file

if (-e $file) then

Page 34: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The clean Script

echo cannot delete $file

else

echo "***** $file deleted"

endif

endif

break ## to handle next file

case n: ## no, don't remove file

echo "***** $file not deleted"

break ## to handle next file case m: ## display file with more

more $file; continue ## back to while loop

case t: ## show tail of file

tail $file; continue

case \!: ## shell escape

echo command:

Page 35: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The clean Script

eval $< ## in this command the var $file can be used

continue

case q: ## quit from clean

exit(0)

default: ## help for user

echo "clean commands: followed by RETURN\

y yes delete file\

n no, don't delete file, skip to next file\

m display file with more first\

t display tail of file first\

\! shell escape\

q quit, exit from clean"

endsw

end ## of while

end ## of foreach

Page 36: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The ccp Script

#!/bin/csh

## csh script : ccp --- conditional copy

## usage: ccp from to [ file ... ]

## where: `from' the source directory

## `to' the destination directory

## [file ... ] an optional list of files to be copied,

## otherwise, all files in `from' will be processed

if ($#argv < 2) then

echo usage: ccp from to "[ file ... ]"; exit(1)

else if (! -d $1 || ! -d $2) then

echo usage: ccp from to "[ file ... ]"; exit(1)

endif

Page 37: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The ccp Script

set dir = `pwd`; chdir $2; set to = `pwd`

chdir $dir; chdir $1; ## now in from-dir

if ($#argv == 2) then

set files = *

else

set files = ( $argv[3-] )

endif

foreach file ($files)

if ( -d $file ) continue ## skip directories

if (! -e $to/$file) then

echo $to/$file is a new file

cp $file $to; continue

endif

# if file in $from is more recent then cp

find $file -newer $to/$file -exec cp $file $to \;

end

Page 38: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The total Script

#!/bin/csh

## csh script: total

## --- compute total disk space in bytes for a directory hierarchy

## a recursive script

if ( $#argv == 1 && -d $1) then

set x = `/bin/ls -l -d $1`

else

echo usage : $0 directory; exit(1)

endif

set count = $x[4] ## initialize byte count

Page 39: Shell Scripts 4 A shell usually interprets a single line of input, but we can also create a file containing a number of lines of commands to be interpreted

The total Script

foreach file ( $1/* $1/.* )

if ( -f $file ) then

set x = `/bin/ls -l $file`

@ count = $count + $x[4]

else if ( $file:t == "." || $file:t == ".." ) then

continue

else if ( -d $file ) then

set y = `$0 $file` ## recursive call

@ count = $count + $y

else

echo $file not included in the total >>! /tmp/total.file

endif

end

echo $count