Linux Administration 321 Shell Scripting Shell Scripts A

  • Slides: 40
Download presentation
Linux Administration 321 Shell Scripting

Linux Administration 321 Shell Scripting

Shell Scripts • A shell usually interprets a single line of input, but we

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)

CSH Input Processing • CSH transforms each command before it is executed by applying

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

Shell Script Invocation • A shell script may be invoked either explicitly: • csh

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

A Simple Example #this script consults an on-line telephone database grep -i $1 $HOME/phonenumbers

A Simple Example #this script consults an on-line telephone database grep -i $1 $HOME/phonenumbers A positional parameter A comment An environment variable • To make this script executable, chmod +rx • Now it can be run from the command line

Shell Script Basics • A shell script consists of a sequence of built-in and

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.

Executable Text Files • When the shell executes a nonbuilt-in command (i. e. a

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

Positional Parameters • Parameters can be passed to the script from the command line.

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)

CSH Scripts • The CSH scripting language is based on the C language. •

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?

Control Flow in CSH Scripts • Rather than just executing a predetermined sequence of

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

Control Flow in CSH Scripts • The foreach command is used to execute a

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

The foreach Command #!/bin/csh foreach x ( * ) echo Changing mode for $x

The foreach Command #!/bin/csh foreach x ( * ) echo Changing mode for $x chmod +rx $x end • Consider changing mode only for. exe files.

The if Command • Logical branching is provided by the if command: if (expr

The if Command • Logical branching is provided by the if command: if (expr ) simple-command if ( expr ) then commandlist 1 [else commandlist 2] endif

The if Command ##check and set parameters if ( $#argv > 2 || $#argv

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

The switch Command • A multiway alternative is provided by the switch command: switch

The switch Command • A multiway alternative is provided by the switch command: switch ( str ) case pattern 1: commandlist 1 breaksw case pattern 2: commandlist 2 breaksw … default: commandlist endsw

The switch Command #!/bin/csh ## append $1 to $2 or standard input to $1

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

The while Command • The while command executes commands until an expression evaluates to

The while Command • The while command executes commands until an expression evaluates to zero: while ( expr ) commandlist end • Example set i = $#argv while ($i) echo $argv[$i] @ i-end

Numerical Computations • Notice the ‘@’ in front of the i-- this allows a

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++

Other Control Flow Constructs • The goto command (goto word) provides an unconditional branch

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.

Expressions • Expressions in csh are similar to those in C: • Logical operators

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

Expressions • CSH adds file queries to test the status of a file •

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 ({ command 1 } && { command 2 } || { command 3 } then

Variables • There are four kinds of variables: 1. Positional parameters (e. g. $1

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 set @ k set @ command: dir = $cwd list = (a b c d) = $j + 1 y = “$list” A multivalued variable Value of k is a string Use doublequotes for a multivalued variable

Variables • To select a portion of a multivalued variable, use $var[ selector ]where

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.

Variable Modifiers • The value of a variable can be modified before it is

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

Variable Modifiers #!/bin/csh set files = * foreach file ( $files ) echo $file

Variable Modifiers #!/bin/csh set files = * foreach file ( $files ) echo $file if ( $file: e == for ) then mv $file {$file: r}. f 77 endif end

Special Substitutions • To examine whether a variable is set or not use $?

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: vt 100’ endif • The special variable $$ substitutes the process number of the shell executing the script.

Special Substitutions #!/bin/csh ## Reminder service using calendar and mail set tfile = /tmp/remind_$$

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

Input and Output • The command echo words is used to display zero or

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.

The Here Document • It is possible to include input that is normally entered

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

The Here Document ## script name: timestamp ## usage: timestamp file cat >> $1

The Here Document ## script name: timestamp ## usage: timestamp file cat >> $1 <<here ********** RECEIVED by $user on `hostname` `date` here

The findcmd Script #!/bin/csh ## this procedure finds where given command is on search

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

The append Script #!/bin/csh ## append $1 to $2 or standard input to $1

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

The clean Script ## csh script: clean ## helps to rm unwanted files from

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 = *

The clean Script foreach file ($files) if (! -f $file ) then continue ##

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

The clean Script echo cannot delete $file else echo "***** $file deleted" endif break

The clean Script echo cannot delete $file else echo "***** $file deleted" endif break ## to handle next file case n: ## no, don't remove file echo "***** $file not deleted" break ## to handle next file ## display file with more $file; continue ## back to while loop case t: ## show tail of file tail $file; continue case !: ## shell escape echo command: case m:

The clean Script eval $< ## in this command the var $file can be

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

The ccp Script #!/bin/csh ## csh script : ccp --- conditional copy ## usage:

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: endif ccp from to "[ file. . . ]"; exit(1)

The ccp Script set dir = `pwd`; chdir $2; set to = `pwd` chdir

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

The total Script #!/bin/csh ## csh script: total ## --- compute total disk space

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

The total Script foreach file ( $1/* $1/. * ) if ( -f $file

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