Unix Lecture 5 Unix Shell Scripts LIN 6932

  • Slides: 35
Download presentation
Unix Lecture 5 Unix Shell Scripts LIN 6932 1

Unix Lecture 5 Unix Shell Scripts LIN 6932 1

Command Coordination ; && || command 1 ; command 2 Interpretation: Do command 1.

Command Coordination ; && || command 1 ; command 2 Interpretation: Do command 1. Then do command 2 Description: The semicolon links two commands that are executed by the shell in simple sequential order. This means that csh will run the first command in the sequence, then once that command is finished, it will run the next command. Linking commands with semicolons is analogous to executing them as separate commands. That is, the command line below: % cd ~/public_html ; ls *. html is equivalent to this: % cd ~/public_html % ls *. html LIN 6932 2

Command Coordination ; && || command 1 && command 2 Interpretation: Do command 2

Command Coordination ; && || command 1 && command 2 Interpretation: Do command 2 only if command 1 executes successfully (and not otherwise). Description The double-ampersand links two commands as a very simple case of a conditional. This means that there is a condition under which command 2 is executed: namely only if command 1 executes successfully. This is only a little more complex than the semicolon operator. For example, giving a command like this: % clear && cal will attempt to run the clear command first. If and only if the clear command works (i. e. , returns an exit status of 0), the shell will run the cal command. If the clear command does not work (i. e. , returns a non-zero exit status), then the cal command is not even attempted. LIN 6932 3

Command Coordination ; && || command 1 || command 2 Interpretation Do command 1

Command Coordination ; && || command 1 || command 2 Interpretation Do command 1 or command 2 (but not both). Description: || means something like "OR". The shell will attempt to execute command 1 first. If and only if command 1 fails (i. e. , returns a non-zero exit status), the shell will run command 2. If command 1 exits cleanly, the shell does not even attempt running command 2. For example, if you type something like this: % rm /etc/motd || echo "Sorry, can't remove file. " The shell will attempt to remove the file /etc/motd first. If that works, then nothing else happens. However, if that command doesn't work for any reason (like maybe you don't have permission), the shell will run the echo command, and print the message Sorry, can't remove the file to the screen. Give it a shot to see what we're talking about. LIN 6932 4

Shell Script File • • any collection of csh commands may be stored in

Shell Script File • • any collection of csh commands may be stored in a file, a shell script file csh can be invoked to execute the commands in that file the language used in that file is called shell script language Like other programming languages it has variables and flow control statements: e. g. if-then-else, while, for, goto. LIN 6932 5

Invoking Shell Scripts DIRECT INTERPRETATION % csh filename [arg. . . ] invokes the

Invoking Shell Scripts DIRECT INTERPRETATION % csh filename [arg. . . ] invokes the program csh to interpret the script contained in the file `filename'. INDIRECT INTERPRETATION we insert as the first line of the file #! /bin/csh (by default) Or use the information given when you execute the command % echo $SHELL /usr/local/bin/tcsh AND the file must be made executable using chmod LIN 6932 6

A simple example: listfiles #! /usr/local/bin/tcsh echo "hello, $USER. I wish to list some

A simple example: listfiles #! /usr/local/bin/tcsh echo "hello, $USER. I wish to list some files of yours" echo "listing files in the current directory, $PWD" ls # list files • • $USER and $PWD are standard variables defined by the csh and needn't be defined in the script the variables are expanded when the variable name is inside double quote: the shell sees the string $USER and replaces it with the variable's value then executes the command. LIN 6932 7

Setting Variables Any programming language needs variables. You define a variable as follows: set

Setting Variables Any programming language needs variables. You define a variable as follows: set X will set the variable X to have an empty list as its value and refer to it as follows: $X $X is used to denote the value of the variable X set X = dear LIN 6932 8

A simple example: listfiles 1 #! /usr/local/bin/tcsh set X = dear echo "hello, $X

A simple example: listfiles 1 #! /usr/local/bin/tcsh set X = dear echo "hello, $X $USER. I wish to list some files of yours" echo "listing files in the current directory, $PWD" ls # list files • • $USER and $PWD are standard variables defined by the csh and needn't be defined in the script the variables are expanded when the variable name is inside double quote: the shell sees the string $USER and replaces it with the variable's value then executes the command. LIN 6932 9

Command Arguments Most commands have arguments, and these are accessible via the shell variable

Command Arguments Most commands have arguments, and these are accessible via the shell variable $argv. The first parameter will be $argv[1] , the second $argv[2] , and so on. The number of such arguments is $#argv. Consider the following script file, named swap: #! /bin/csh set tmp = $argv[1] cp $argv[2] $argv[1] cp $tmp $argv[2] If you have files x and y, and type % swap x y then the new contents of x would be what is in y. LIN 6932 10

Command Arguments Most commands have arguments, and these are accessible via the shell variable

Command Arguments Most commands have arguments, and these are accessible via the shell variable $argv. The first parameter will be $argv[1] , the second $argv[2] , and so on. The number of such arguments is $#argv. Consider the following script file, named swap: #! /usr/local/bin/tcsh set tmp = $argv[1] cp $argv[2] $argv[1] cp $tmp $argv[2] If you have files x and y, and type % swap x y then the new contents of x would be what is in y. LIN 6932 11

Flow Control Statements Conditional If … then … endif Conditionals are commands which are

Flow Control Statements Conditional If … then … endif Conditionals are commands which are executed only if a certain condition is true. Syntax of the if conditional: if ( expression ) then command endif If expression is true, then command is executed. If expression is false, command is not executed. LIN 6932 12

Flow Control Statements Conditional If … then … endif # over 100 -- checks

Flow Control Statements Conditional If … then … endif # over 100 -- checks if a number is greater than 100 if ( $1 > 100 ) then echo ”That’s a big number!” endif LIN 6932 13

A note on Relational Operators == != < > <= >= equal to not

A note on Relational Operators == != < > <= >= equal to not equal to less than greater than less than or equal to greater than or equal to LIN 6932 14

Flow Control Statements Conditional If expression is true, more than one command can be

Flow Control Statements Conditional If expression is true, more than one command can be executed if ( command 1 command 2. . . endif expression ) then # these commands are executed if expression is true LIN 6932 15

Flow Control Statements Conditional # over 100 add -- checks if a number is

Flow Control Statements Conditional # over 100 add -- checks if a number is greater than 100, adds 1 to # it and then subtracts 2 from it. if ( $1 > 100 ) then echo ”That’s a big number!” echo "$1 is a big number. " echo ”But `expr $1 + 1` is even bigger. ” echo `expr $1 - 2` endif Recall: The backquotes ` around a command signify COMMAND SUBSTITUTION: The output from the backquoted command is included within the command line for another command. LIN 6932 16

Flow Control Statements Conditional an if statement can also have a set of commands

Flow Control Statements Conditional an if statement can also have a set of commands which run if expression is false, using the else command: if ( command 1 command 2. . . else command 11 command 12. . . endif expression ) then # these commands are executed if expression is true # these commands are executed if expression is false LIN 6932 17

Flow Control Statements #! /bin/csh Conditional # string_check -- checks two strings # first,

Flow Control Statements #! /bin/csh Conditional # string_check -- checks two strings # first, make sure the user typed in two arguments following the command if ( $# != 2 ) then echo "This script needs exactly two (2) arguments. " echo "Exiting. . . (annoyed)" exit 666 endif # now, compare them if ( $1 == $2 ) then echo "$1 and $2 are the same, aren't they? " else echo "$1 and $2 are different, aren't they? " endif LIN 6932 18

Flow Control Statements foreach ‘loop’ The syntax of foreach loop construct is foreach var

Flow Control Statements foreach ‘loop’ The syntax of foreach loop construct is foreach var ( wordlist ) command(s) end The command(s) is executed once for each “word” (or item) in the wordlist, and each time the variable var will contain the value of that word. LIN 6932 19

Flow Control Statements foreach ‘loop’ % vi marks 16 - | - | 19

Flow Control Statements foreach ‘loop’ % vi marks 16 - | - | 19 - | - | 16 A | A | B 16 - | - | 20 A | A | | | A A A | | | | | A A LIN 6932 | | | B A |Fred Dexter |Waqas Younis |David Gower |Mickey Stewart |Graham Thorpe 20

Flow Control Statements foreach ‘loop’ % vi countmarks #!/bin/csh # counts the number of

Flow Control Statements foreach ‘loop’ % vi countmarks #!/bin/csh # counts the number of students associated with a number of # particular marks foreach number(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) set ms=`grep "^$number " marks | wc -l` if ($ms != 0) then echo “$ms ' student(s) got ' $number marks” endif end Note: set ms= will set the variable ms to have the value that corresponds to the output of the grep and wc command line utilities. LIN 6932 21

Flow Control Statements foreach ‘loop’ % chmod +x countmarks 3 student(s) got 16 1

Flow Control Statements foreach ‘loop’ % chmod +x countmarks 3 student(s) got 16 1 student(s) got 19 1 student(s) got 20 ; countmarks Recall: The semicolon ; links two commands that are executed by the shell in simple sequential order; csh will run the first command in the sequence, then once that command is finished, it will run the next command. LIN 6932 22

Flow Control Statements foreach ‘loop’ Example: % mkdir city; cd city; mkdir sf ny

Flow Control Statements foreach ‘loop’ Example: % mkdir city; cd city; mkdir sf ny la; touch sf/a ny/b la/c Note: touch is a standard Unix program used to create a blank file; it is also used to change a file's access and modification timestamps. LIN 6932 23

Flow Control Statements foreach ‘loop’ Example: % mkdir Try; cd Try; mkdir d 1

Flow Control Statements foreach ‘loop’ Example: % mkdir Try; cd Try; mkdir d 1 d 2 d 3; touch d 1/a d 2/b d 3/c % vi check #!/bin/csh set start=`pwd` set command=$0 foreach name (`ls`) if (-d $name) then (cd $name ; $start/$command) ; echo "end of directory $name" else echo "$name is a file" endif end LIN 6932 24

Flow Control Statements foreach ‘loop’ Example: % chmod +x check is a file c

Flow Control Statements foreach ‘loop’ Example: % chmod +x check is a file c is a file end of directory b is a file end of directory a is a file end of directory ; check la ny sf LIN 6932 25

Del Script #! /bin/csh # usage: del * foreach name ($argv) if ( -f

Del Script #! /bin/csh # usage: del * foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)? " else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw LIN 6932 end 26

Del Script #! /bin/csh foreach name ($argv) # $argv shell variable for an argument

Del Script #! /bin/csh foreach name ($argv) # $argv shell variable for an argument of a command if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)? " else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end LIN 6932 27

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then #tests

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then #tests to see if the file whose name is in $name is an ordinary file, as opposed to a directory file. echo -n "delete the file '${name}' (y/n/q)? " else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end LIN 6932 28

A note on File Operations Using the if command, filenames can be tested for

A note on File Operations Using the if command, filenames can be tested for the following: -d filename true if -e filename true if -f filename true if -o filename true if -r filename true if -w filename true if -x filename true if -z filename true if filename is a directory filename exists filename is a text file you own filename is readable filename is writable filename is executable filename is empty LIN 6932 29

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then echo

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)? ” #The echo -n prevents a skip to a new line; the -n option of echo tells the shell not to print the newline # character, so that our answer, y/n/q, will be on the same line. else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end LIN 6932 30

Del Script echo -n vs. echo The echo utility writes any specified operands, followed

Del Script echo -n vs. echo The echo utility writes any specified operands, followed by a newline n character The following option is available: -n Do not print the trailing newline character n. LIN 6932 31

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then echo

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)? ” else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< #the symbol switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end $< means the input from the keyboard LIN 6932 32

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then echo

Del Script #! /bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)? " else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: #Control flow is switched to where the first match occurs continue #go to the top of the enclosing loop case q: exit case y: rm -r $name continue endsw end LIN 6932 33

A note on SWITCH command The switch command takes the general form: switch ($variable)

A note on SWITCH command The switch command takes the general form: switch ($variable) case pattern 1: action breaksw case pattern 2: action breaksw. . . default : action endsw # Starts a switch # Defines a label in a switch command LIN 6932 34

Del Script case y: rm -r $name # rm stands for "remove" and the

Del Script case y: rm -r $name # rm stands for "remove" and the -r option means recursively, if an argument of # rm -r is a directory, the rm -r command will remove that directory, and all the # files (and subdirectories, etc. ) within it. # You can also use *, a wildcard for everything; rm will go through the current # working directory and remove all the files in it, and also through every subdirectory # and remove all the files in them. In short, # rm -r * deletes everything in the current directory and below. LIN 6932 35