Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2...

37
Shell Programming

Transcript of Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2...

Page 1: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Shell Programming

Page 2: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

An example tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg <file1 >file2– encrypts file1 into file2

record this command with a script file– myencrypt

#!/bin/sh

tr abcdefghijklmnopqrstuvwxyz \

thequickbrownfxjmpsvalzydg– mydecrypt

#!/bin/sh

tr thequickbrownfxjmpsvalzydg \

abcdefghijklmnopqrstuvwxyz

Page 3: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

An example chmod the files to be executable

% chmod u+x myencrypt mydecrypt run them as normal commands

% ./myencrypt < file1 > file2

% ./mydecrypt < file2 > file3

% diff file1 file3

Page 4: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Shell Scripts (1)

A Shell Script is simply a text file with UNIX commands in it

Shell Scripts usually begin with a #! and a shell name– For example: #!/bin/sh– If they do not, the user's current shell will be used

Any UNIX command can go in a Shell Script– these commands are executed in order or in the flow

determined by the control statements– much like a program in a language like Pascal, C or Java

Different shells have different control structures– the #! line is very important – we will generally write shell scripts with the Bourne (sh) shell

Page 5: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Shell Scripts (2) Why Write Shell Scripts?

– to avoid repetition if you do a sequence of steps with standard UNIX

commands over and over, why not just type one command?

– to automate difficult tasks many commands have subtle and difficult options

which you don't want to figure out every time

Page 6: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Command Line Arguments (1) Shell Scripts would not be much useful if we

could not pass arguments to them on the command line

Shell Script arguments are "numbered" from left to right– Inside the script refer to each argument by this

number with a $ in front $1 - first argument after command $2 - second argument after command ... up to $9

– These are called Positional Parameters and can be used much like shell variables

Page 7: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Command Line Arguments (1) Example 1: get a particular line of a file

– Write a command with the format:

getlineno linenumber filename

#!/bin/sh

head -$1 $2 | tail –1 Other variables related to arguments

$0 name of the command running $* All the arguments (even if there are more than

9) $# the number of arguments

Page 8: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Command Line Arguments (2) Example 2: print the oldest files in a directory

#! /bin/sh# oldest -- examine the oldest parts of a directoryHA=$1shiftls -lt $* | tail +2 | tail $HA

The shift command shifts all the arguments to the left– $1 = $2, $2 =$3, $3 = $4, ...– $1 is lost (but we have saved it in $HA)– useful when there are more than 9 arguments

The "tail +2" command removes the first line (why do this?)

Page 9: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Bourne Shell Variables (1)

There are three basic types of shell variables– Positional variables

$1, $2, $3, ..., $9 -- we've seen these– Keyword variables

like PATH, HA, and anything else we may define– Special variables

$*, $# -- all the arguments, the number of the arguments

$$ -- the process id of the current shell $? -- return value of last foreground process

to finish

-- more on this one later and others you can find out about with man sh

Page 10: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Bourne Shell Variables (2) Bourne shell variables are much like variables

in a standard programming language– Examples:

PATH=$PATH:$HOME/binHA=$1PHRASE="House on the hill"

if the value you wish to assign has spaces, RHS (right hand side) must be quoted

if you want sub-shells and commands to be able to look at these variables, you must export them

export PATH HA PHRASE

Note: no spacearound =

Page 11: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Bourne Shell Variables (3) It is also sometimes useful to do numerical

computations with shell variables– like everything else in UNIX this is done with a

command:expr

– expr evaluates very simple expressions of constants– For example:

obelix[1]% expr 3 + 47obelix[2]% expr \( 3 + 4 \) \* 5 % 65

– Results go to standard output how do you use the results?

note: all operands andoperators are separatedby spaces

note: all special charsmust be quoted or escaped

Page 12: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Bourne Shell Variables (4) shell variables are expanded first, then the operands

are given to the shellobelix[3]% a=5obelix[4]% expr $a + 16

Use results of expr with backquotes: `...`obelix[5]% a=`expr \( $a + 1 \)`obelix[6]% echo $a6

expr supports the following operators:– arithmetic operators: +,-,*,/,%– comparison operators: <, <=, ==, !=, >=, >– boolean/logical operators: &, |– parentheses: (, )– precedence is the same as C, Java

Page 13: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Control Statements (1) Control statements control the flow of execution in an

imperative programming language– this is how Java, C, C++, .... and Shells work– non-imperative languages like lisp, ML, Prolog, Miranda,...

may work differently

Without control statements execution within a shell scripts executes one statement after the other– each statement may be quite complicated and may invoke

other UNIX commands (or even the same command...)

The three most common types of control statements:– conditionals: if/then/else, switch, case, ...– loop statements: while, for, repeat, do, ...– branch statements: subroutine calls (good), goto (bad)

Page 14: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Control Statements (2) Both loops and conditions generally "test" something

– essentially comes down to a binary decision In a Bourne shell script, the only thing you can test is

whether or not a command is "successful"– every well behaved command returns back a return code

0 if it was successful non-zero if it was unsuccessful (actually 1..255)

examine the return code of the previous UNIX command executed in a shell with $?

obelix[7]% grep “bma" < /dev/nullobelix[8]% echo $?1obelix[9]% echo “bma" | grep “bma"obelix[10]% echo $?0

Page 15: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Conditional (1)The if statement Simple form:

if decision_command_1

then

command_set_1

fi

Example:if grep “bma“ $1 >/dev/null

then

echo -n "It\'s"

echo "there"

fi

grep returns 0 if it finds something returns non-zero otherwise

redirect to /dev/null so that"intermediate" results do not getprinted

Page 16: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Conditional (2) Else form:

if decision_command_1

then

command_set_1

else

command_set_2

fi

Example:if grep "UNIX" myfile >/dev/null

then

echo "UNIX occurs in file"

else

echo "UNIX does not occur in file"

fi

• The indentation used in these examples is "optional" (as in most programming languages)• Good indentation is very highly recommended

• Required for cs211 assignments

Page 17: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Conditional (3) Elif form:

if decision_command_1then

command_set_1elif decision_command_2

command_set_2...fi

Example:if grep "UNIX" myfile >/dev/nullthen

echo "UNIX occurs in file"elif grep "DOS" myfile >/dev/null

echo “Unix does not occur, but DOS does"else

echo “nobody is there"fi

Page 18: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Conditional (4) Alternatively, statements can be separated by a

semicolon (;)– For example:

if grep "UNIX" myfile; then echo "Got it"; fi– This actually works anywhere in the shell.

E.g.

obelix[11]% cwd=`pwd`; cd $HOME; ls; cd $cwd

Page 19: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Conditional (5) Sometimes it is useful to have a command which does

"nothing" The : (colon) command in UNIX does nothing besides

having its parameters expanded (and ignored).– it returns a return code of 0

Example:#!/bin/sh# pgrep: a polite grepif grep $*then

:else

echo "Sorry, but '$1' was not there..."fi

Page 20: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (1) File tests:

test –f file does file exist and is not a directory?test –x file does file exist and is executable?test –s file does file exist and is longer than 0 bytes?test –z string is string of length 0 (i.e., the null string)?

See man test(1) for more options For example you can write:

#!/bin/sh# safermif test –f $1then

mv $1 $1.`date '+%Y-%M-%d:%H:%M.%S'`fi

gives the date as1999-10-7:9:30.23

Page 21: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (2)

String tests– test can compare strings

test string1 = string2 does string1 equal string2?

test string1 != string2 does string1 not equal string2?– For example, you might do something different depending

upon your TERM variable:

if test $TERM = vt100; then

stty erase '^?'

resize

elif test –z $TERM; then

stty erase '^H'

fi

stty configures variouskeys on the keyboard(you can look up details)

Page 22: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (3) Integers can also be compared

– use –eq, -ne, -lt, -le, -gt, -ge For example:

#!/bin/sh# smallarg: print the smallest line argsif test $# -eq 1; then echo $1elif test $# -gt 1; then A=$1 shift B=`smallarg $*` if test $A -le $B; then echo $A else echo $B fifi

Recursion: Cooooool

Page 23: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (4) The test program has an alias as [

– add in a matching ] at the end– this is supposed to be a bit easier to read#!/bin/sh

# smallarg: print the smallest line argsif [ $# -eq 1 ]; then echo $1elif [ $# -gt 1 ]; then A=$1; shift B=`smallarg $*` if test $A -le $B; then echo $A else echo $B fifi

Page 24: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (1) File tests:

test –f file does file exist and is not a directory?test –x file does file exist and is executable?test –s file does file exist and is longer than 0 bytes?test –z string is string of length 0 (i.e., the null string)?

See man test(1) for more options For example you can write:

#!/bin/sh# safermif test –f $1then

mv $1 $1.`date '+%Y-%M-%d:%H:%M.%S'`fi

gives the date as1999-10-7:9:30.23

Page 25: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (2)

String tests– test can compare strings

test string1 = string2 does string1 equal string2?

test string1 != string2 does string1 not equal string2?– For example, you might do something different depending

upon your TERM variable:

if test $TERM = vt100; then

stty erase '^?'

resize

elif test –z $TERM; then

stty erase '^H'

fi

stty configures variouskeys on the keyboard(you can look up details)

Page 26: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (3) Integers can also be compared

– use –eq, -ne, -lt, -le, -gt, -ge For example:

#!/bin/sh# smallarg: print the smallest line argsif test $# -eq 1; then echo $1elif test $# -gt 1; then A=$1 shift B=`smallarg $*` if test $A -le $B; then echo $A else echo $B fifi

Recursion: Cooooool

Page 27: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The test Program (4) The test program has an alias as [

– add in a matching ] at the end– this is supposed to be a bit easier to read#!/bin/sh

# smallarg: print the smallest line argsif [ $# -eq 1 ]; then echo $1elif [ $# -gt 1 ]; then A=$1; shift B=`smallarg $*` if test $A -le $B; then echo $A else echo $B fifi

Page 28: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Command Line Input

The read command reads one line of input from the terminal and assigns it to variables give as arguments

Syntax read var1 var2 var3 ... action: reads a line of input from standard input assign var1 to first word, var2 to second word, ... the last variable gets any excess variables on the line

Example:obelix[11]% read X Y ZHere are some words as inputobelix[12]% echo $XHereobelix[13]% echo $Yareobelix[14]% echo $Zsome words as input

Page 29: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The While Loop (1) While loops repeat statements while the return code of some

UNIX command is 0 The syntax is:

while decision commanddo

command_setdone

Example 1:#!/bin/sh# print numbers from 1 to $1COUNT=1while [ $COUNT –le $1 ]; do echo –n $COUNT " "

COUNT=`expr $COUNT + 1`doneecho

Page 30: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

The While Loop (2) Example 2:

– a more conventional approach to finding the smallest argument

#!/bin/sh

# smallarg: print the smallest line args

smallest=$1

shift

while [ $# -gt 0 ]; do

if [ $1 –lt $smallest ]; then

smallest=$1

fi

shift

done

echo $smallest

Page 31: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

For Loops (1) For loops allow the repetition of a command for a specific set of

values– E.g.: each argument on a line, each file in a set of files

Unlike many programming languages, for loops in shell script are not numeric or counted– we can use a while loop for this

Syntax:for var in value1 value2 ...

do

command_set

done

– command_set is executed with each value of var (value1, value2, ...) in sequence

Page 32: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

For Loops (2) For Loop Example 1:

#!/bin/sh

# timestable – print out a multiplication table

echo –n "Which times table do you want?"

read Table

for i in 1 2 3 4 5 6 7 8 9 10

do

Value=`expr $i \* $Table`

echo $i x $Table = $Value

done

Page 33: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

For Loops (3) For Loop Example 2:

#!/bin/sh# file-poke – tell us stuff about filesfor file in $*; do

echo –n "$file "if [ -s "$file" ]; then echo is full.else echo is empty.fi

done– command goes through all files on the command line

these could be from filename expansion – we might typeobelix[16]% file-poke *

Inside file-poke, $* will consist of a list of all files in the current directory

Page 34: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

For Loops (4) For Loop Example 3:

#!/bin/sh

# findcmd – show where command $1 is found in $PATH

for prog in $*; do

for dir in `echo $PATH | tr ':' ' '`; do

if [ -x $dir/$prog ]; then

echo $dir/$prog

fi

done

done

PATH is : separatedconvert to space separated

Note: doubly nested loop

Page 35: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Piping Input to a Loop

The standard input can be piped into a while or for loop– take a look at the output from the who command:

obelix[15]% whowatt ttyp3 Aug 27 11:30 (aquarium.scl.csd.uwo.ca)watt ttyp4 Sep 30 21:19 (diamond.admin.csd.uwo.ca)mwg ttyp2 Oct 6 16:57 (heffalump.csd.uwo.ca)

– Now write a command to make this output "friendly":#!/bin/shwho | while read user tty month date time therestdo echo –n $user is on $tty and has been since $month $date at $time. if [ ! –z "$therest" ]; then echo " $user is connected from $therest" else

echo fidone

Pipe output of who into the while loop

read reads one line at a timefrom the standard inputreturns non-zero user code at end-of-file

Page 36: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Piping Output from a loop The output from a loop can also be piped into the next command For example:

#!/bin/sh# findcmd2 – show where command $1 is found in $PATH# – and print extended information about it for prog in $*; do

for dir in `echo $PATH | tr ':' ' '`; do if [ -x $dir/$prog ]; then echo $dir/$prog

fi donedone | while read cmd; do

ls –l $cmd done;

Output of for loop is pipedinto while loop, where itis read, one line at a time

Page 37: Shell Programming. An example u tr abcdefghijklmnopqrstuvwxyz \ thequickbrownfxjmpsvalzydg file2 –encrypts file1 into file2 u record this command with.

Piping In and Out of a Loop A more complex example:

#!/bin/sh

# lookfor – watch who output for specific users

who |

while read user tty mon dt year therest; do

for watch in $*; do

if [ $watch = $user ]; then

echo $watch is on

fi

done

done |

sort | uniq –c | sed –e 's/ *\([0-9][0-9]*\) \(.*\)/\2 \1 times/'

make lines uniquebut include count

grab count into \1

re-order forprintout