260 likes | 386 Vues
Shell Control Statements and More. CS465 - UNIX. while [ condition ] do command(s) done. Same condition syntax as if statement Begin and end of command block defined by keywords do ... done Loops while condition is TRUE. while statement. $ cat wake #!/bin/sh resp="n"
E N D
Shell Control Statementsand More CS465 - UNIX
while [ condition ] do command(s) done Same condition syntax as if statement Begin and end of command block defined by keywords do...done Loops while condition is TRUE while statement
$ cat wake #!/bin/sh resp="n" while [ "$resp" != "y" ] do echo "Wakeup [y/n]? " read resp done $ while Loop Example #1 $ wake Wakeup [y/n]? n Wakeup [y/n]? Y Wakeup [yes/no]? y $
$ cat fac #!/bin/sh echo "Enter number: " read num fac=1 loop=1 while [ $loop -le $num ] do fac=`expr $fac \* $loop` loop=`expr $loop + 1` done echo "The factorial of $num is $fac" $ while Loop Example #2 • $ fac • Enter number: • 5 • The factorial of 5 is 120 • $
while example #3 $ cat lines while [ "$input" != done ] do echo 'Enter a filename, or "done":' read input if [ "$input" != done ] then lines=`wc –l < $input` echo "$input has $lines lines" fi done $ $ lines Enter a filename, or "done": shoes shoes has 12 lines Enter a filename, or "done": done $
while example #4 $ cat sayhi #! /bin/sh # $* = list of names count=$# while [ count -gt 0 ] do echo Hello $1 count=`expr $count - 1` shift done exit 0 $ sayhi Sue Joe Bob Hello Sue Hello Joe Hello Bob $
Student Exercise • Write a shell script called up, that will move you up in the directory structure • If no arguments, move up ONE directory • If one argument, it should be a number, telling how many directories to move up • Usage Example: $ pwd /usr/home/faculty/small000 $ . up 2 $ pwd /usr/home $ . up $ pwd /usr
Exercise Sample Solution #! /bin/sh # $1 = number of levels to go up # (if no parameters, go up one level) # if [ $# -eq 0 ] then count=1 else count=$1 fi while [ $count -gt 0 ] do cd .. count=`expr $count - 1` done exit 0
for Statement • The for statement is used to repeat commands for known or “fixed” values • Unlike C programming, the for loop usually repeats tasks for “arguments” that are either issued from the script or a stated directory after for statement.
for variable in list do command(s) done variableis a variable name; don't use $ list is a space-separated list of strings. Each element of the list will be assigned to variable one at a time, and the command block will be executed. Within the command block, use $variable to use the value that has been assigned. for statement
for example #1 $ cat colorscript #!/bin/sh for color in red yellow blue do echo $color done echo "the end" $ colorscript red yellow blue the end $
for example #2 Note: If the “in ___” part is omitted, for defaults to “in $* $ cat userdirs #!/bin/sh for user in $* do echo Directory for: $user ls -F /home/${user} done $ $ userdirs jmsmith krjones Directory listing for: jmsmith cprogs/ dotask* xfile diskfile mbox Directory listing for: krjones mbox prog1.c prog2.c $
for example #3 • $ cat printall • #!/bin/sh • for file in * • do • if [ -f $file ] • then • echo "Print $file [y/n]? " • read resp • if [ $resp = "y" ] • then • lpr $file • fi • fi • done • $ $ printall letter1 names Print letter1 [y/n]? y Print names [y/n]? n
case string in choice) command(s) ;; choice) command(s) ;; esac Very similar to C switch statement: executes the commands after a choice that matches string. Double-semicolon ends a block of commands, like the C break statement. If you skip the ;; you will keep going into the next block . * as a choice will match any string, and can be used to set a default esac ends the statement. case statement
case Example #1 echo Enter command and filename read cmd file case "$cmd" in list) ls -l "$file" ;; count) wc -l "$file" ;; *) echo "command $cmd is not implemented" ;; esac
case Example #2 $ cat yesno #! /bin/sh echo –n 'Yes or No (y/n)? ' read choice case $choice in "Y" | "y") echo You chose Yes;; "N" | "n") echo You chose No;; *) echo Invalid choice;; esac exit $ yesno Yes or No (Y/N)? N You chose No $
case Example #3 The following will be a script to: Give user a choice of what to do with the files listed as arguments: Copy to a subdirectory Concatonate or Delete Carry out the action chosen, prompting for the subdirectory or file to concatonate into, as needed. Display a message confirming action was done.
case Example #3 $ cat files #! /bin.ksh # script parameters = files to operate on cat << STOP M) Move Files C) Concatonate Files D) Delete Files Enter choice: STOP read choice (Continued on next slide)
case Example #3 (continued) case $choice in "m"|"M") echo Move files to which subdir? read subname if [ ! -d $subname ] then mkdir $subname fi mv $* $subname echo Files moved to subdir $subname ;; "c"|"C") echo File to place concatonation in? read fname if [ -f $fname ] then echo Error - $fname already exists else cat $* > $fname echo Files concated into $fname fi ;;
case Example #3 (continued) "d"|"D") rm $* echo Files $* have been deleted ;; *) echo Invalid Choice -- No Can Do ;; esac exit 0 $ files file1 file2 M) Move Files C) Concatonate Files D) Delete Files Enter choice: C File to place concatonation in? combo Files concated into combo $
How the Shell Finds a Command • The shell searches a list of directories for an executable file with the same name as the command given. • The list of directories is stored in the PATH variable $ PATH=/bin:$PATH (sh/ksh) • If there is a match in more than one directory, the shell uses the first one it finds. • To run a command not in one of these directories, give a pathname (relative or absolute) instead. $ ~/progs/dosomething
Built-In Commands • Some commands are built into the shell kernel. • The echo command, for example, is often builtin, for efficiency. • You can find out where the shell is getting a particular command using the “which” command in any shell: $ which echo echo: shell built-in command. $ which cat /usr/bin/cat $
More Environment Variables Predefined Environmental Variables: PPID shell’s parent’s process id IFS list of command line word delimiters (default is list is space, tab & newline) PS1 your shell prompt (default is $) PS2 your input prompt (default is >) SHENV directory where your .profile is located (default is $HOME)
Files Run at Login • System-wide login file /etc/profile • Personal login file $HOME/.profile • Personal environment file • Set by $ENV Usually $HOME/.kshrc
Sample Bourne .profile # Set PATH PATH=$PATH:. export PATH # Set environmental variable file ENV=$HOME/.envsetup # Set shell variables PS1='Command? ' # Display status information date echo "Currently logged in users:“ users
Directory in prompt To include directory in prompt, put these lines in your .profile file: PS1='$PWD $ ' or PS1="`pwd`$ " export PS1