330 likes | 451 Views
第 9 章 Shell 编程基础. 脚本变量 算术运算语句 测试语句 分支语句 循环语句 其它语句. 内容概要. shell 变量分类: 环境变量 自定义变量 系统变量. 脚本变量. 脚本变量. 脚本变量. 脚本的参数可以像 shell 命令的参数一样传递给脚本:. $1, $2, ... $9 ${10}, ${11}, ... ${n} ( 只适用于 ksh93). $ cat para_script echo First Parameter entered was $1
E N D
脚本变量 算术运算语句 测试语句 分支语句 循环语句 其它语句 内容概要
shell变量分类: 环境变量 自定义变量 系统变量 脚本变量
脚本变量 脚本的参数可以像shell命令的参数一样传递给脚本: $1, $2, ... $9 ${10}, ${11}, ... ${n} (只适用于ksh93) $ cat para_script echo First Parameter entered was $1 echo Second Parameter entered was $2 echo Third Parameter entered was $3 $0 $1 $2 $3 $ para_script Good Day Sydney First Parameter entered was Good Second Parameter entered was Day Third Parameter entered was Sydney
使用expr命令可以进行整数的四则运算。 expr提供了以下的运算符 优先级 高 低 算术运算语句 expr \( \) 括号 \* 乘法运算 / 除法运算 % 取模运算 + 加法运算 - 减法运算(也可以作为负数的标记)
算术运算语句 $ var1=6 $ var2=3 $ expr $var1 / $var2 2 $ expr $var1 - $var2 3 $ expr \( $var1 + $var2 \) \* 5 45 $ var3=$( expr $var1 / $var2 ) $ echo $var3 2
let命令也可以进行整数的四则运算,但是它的格式更为简洁,不需要在变量前面加上$符号。且不需要在操作数和运算符之间加上空格。 算术运算语句 expr $ var1=6 $ var2=3 $ let var3=var1/var2 $ echo $var3 2
使用let命令可以进行数字进制的转换: 它的基本格式是:base#number base是一个2到36的整数,代表了相应的数字进制(10进制数是默认的进制) number中可以包含大写或小写字母当base的数字大于10 算术运算语句 let 2#100 in binary = 4 8#33 in octal = 27 16#bin hexadecimal = 11 16#2A in base16 = 42
expr与let的比较: expr对于格式的要求比let更为的严格,必须在变量前面加上$符号,操作数与运算符之间必须有空格; expr在进行浮点数的运算时会报错,而let则是只将浮点数的整数部分进行运算; 对于一些符号expr命令必须使用\取消其特殊含义,而let不需要,例如*,(); expr会将运算结果输出到标准输出设备上,而let不会。 Expr 与 let 比较
bc语句提供了浮点数的运算功能,同时bc也是一个功能非常强大的算术运算语句:bc语句提供了浮点数的运算功能,同时bc也是一个功能非常强大的算术运算语句: 进行浮点数的运算 作为一个过滤命令 从标准输入设备或者文件读入运算语句 设置浮点数运算所得到的结果的精度范围 将结果输出到标准输出设备 算术运算语句 bc
bc语句支持的运算操作: ( , ),+ , - , * , / , % , = == , != , < , <= , > , >=(以上这些都类似于let命令) x^y 运算x的y次方 sqrt (x) 求x的平方根 x++ ++x 将x加1(类似C语言的++) x-- --x 将x减1(类似C语言的--) 算术运算语句 bc
bc语句支持的运算操作: bc提供了一个库支持复杂的数学运算 s(x) 求x的sine值 c(x) 求x的cosine值 e(x) 求自然指数e的x次方 l(x) 求x的自然对数 a(x) 求x的arctangent值 精度函数 length(n) 统计有效数字的个数,例如, scale(n) 统计小数点后的数字的个数,例如, 算术运算语句 bc 123.456 has n=6 123.456 has n=3
bc举例: 算术运算语句 bc $ print '1/4' | bc没有设置精度的整数运算 0 $ print 'scale = 3 ; 1/4' | b 设置了明确的精度 0.250 $ print '5.5 * 2.2' | bc通过输入隐式设定精度 12.1 $ bc sqrt( 4 )进行平方根运算 2 运算结果 Ctrl-d结束命令行的交互模式
一条命令的返回值可以用来决定下一条命令是否继续执行:一条命令的返回值可以用来决定下一条命令是否继续执行: 条件执行 command1 && command2 如果(command1执行成功) 那么接着执行(command2) ls s*&& rm s* command1 || command2 如果(command1没有执行成功) 那么接着执行(command2) cd /dir1|| echo Cannot change to /dir1
test命令允许你测试一个给出的条件: test expression or [ expression ] or [[ expression ]] test命令会判断给出的条件并且返回true或者false 测试语句
测试语句 对整数的测试
测试语句 对文件的测试 语法格式: test -[dfrwxs] file $ test –d /home/usera && echo “目录usera存在” $ [ –d /home/usera ]|| echo “目录usera不存在或没有此目录”
测试语句 对字符串的测试 注意:等号与不等号两侧的空格是必不可少的
逻辑运算 测试语句
分支语句 • if 条件为真 • then • 执行这个操作 • else • 执行另一个操作 • fi $ cat active USAGE="$0 userid" if [[ $# -ne 1 ]] then echo "Proper Usage: $USAGE" exit 1 fi if who | grep $1 > /dev/null then echo "$1 is active" else echo "$1 is not active" fi exit $ cat check_user USAGE="$0 username" if [[ $# -ne 1 ]] then echo "Proper usage: $USAGE" exit 2 fi grep $1 /etc/passwd >/dev/null if [[ $? -eq 0 ]] then echo "$1 is a valid user" exit 0 else echo "$1 is not a valid user" exit 1 fi
分支语句 • if 表达式1 • then • 执行操作 • elif 表达式2 • then • 执行另一个操作 • else • 执行其他操作 • fi
分支语句 case $变量 in (匹配1) 执行的操作 ;; (匹配2 | 匹配3) 执行的操作 ;; (*) 其他操作 ;; esac case 关键字 in ( 匹配1 | 匹配2 | ... ) 执行的操作 ;; (*) 其他操作 ;; esac 一个猜字游戏: #!/usr/bin/ksh # Usage: match string # To see how lucky you are feeling today case "$1" in Ace ) print "You are really close." ;; King ) print "Missed it by that much." ;; Queen ) print "Finally!" ;; Jack ) print "I hope you'll get it next time." ;; Ten|10 ) print "Getting close" ;; * ) print "Guess again." ;; esac
循环语句 while while 条件表达式 do 命令 done $ cat information x=1 while [[ $x -lt 9 ]] do echo "It is now $(date)" echo "There are $(ps -e | wc -l) processes running" echo "There are $(who | wc -l) users logged in" x=$(expr $x + 1) sleep 600 done
循环语句 until until 表达式 do 要执行的命令 表达式为真时跳出循环 done $ until cc prog.c > do >vi prog.c > done C编译器返回一个非0值,知道编译成功
循环语句 for for 变量 in 参数列表 do 命令 done $cat count for var in file1 file2 file3 do wc -l $var done $ count 18 file1 20 file2 12 file3 $ cat rm_tmp for FILE in /tmp/* do echo "Removing $file" rm $FILE done
循环语句 for 在ksh93和bash中可用类似C语言的for循环 for (( 初始化 ; 条件 ; 增量 )) do 执行的命令 done 例子: for ((num=0; num <5; num++)) do mv file$num file${num}.bkup done
结束循环 break命令从do…done循环中跳出 continue命令开始下一次do…done循环 select choice in Backup Restore Quit do case $choice in (Backup) find . -print|backup -iqf /dev/rfd0 ;; (Restore) restore -xqf /dev/rfd0 ;; (Quit) break ;; ('') print "What ?" 1>&2 ;; esac done $ for File in * > do > if [[ -d $File ]] > then > continue > fi > file $File > done
read 语句 read命令从标准输出设备读取一行,并赋值给对应 的shell变量中 $ cat delfile # Usage: delfile echo "Please enter the file name:" read name if [[ -f $name ]] then rm $name else echo "Error: $name is not an ordinary file" fi
select 语句 select 命令以编号的形式显示单词或位置参数列表,并输出到标准错误中 select 变量 in 单词1 单词2 ... do case分支结构 done
select 语句 select例子: barn.sh #!/usr/bin/ksh # usage: barn.ksh PS3="Pick an animal: " select animal in cow pig dog quit do case $animal in (cow) print "Moo" ;; (pig) print "Oink" ;; (dog) print "Woof" ;; (quit) exit ;; ('') print "Not in the barn" ;; esac done 输出结果: $ barn.ksh 1) cow 2) pig 3) dog 4) quit Pick an animal: 1 Moo Pick an animal: 2 Oink Pick an animal: 3 Woof Pick an animal: 8 Not in the barn Pick an animal: 4 $
课堂练习 1. 下面这段程序实现什么功能? TERMTYPE=$TERM if [ $TERMTYPE != "" ] then if [ -f /home/team01/customized_script ] then /home/team01/customized_script else echo No customized script available ! fi else echo You do not have a TERM variable set ! fi 2. 写一段脚本,有两个参数,将它们相乘并输出结果
课堂练习答案 1. 下面这段程序实现什么功能? 该脚本将声明一个TERMTYPE变量,其值等于TERM变量。在if语句中将测试TERMTYPE变量如果不为空第二个if语句将判断/home/team01/customized_script是否为普通文件,如果是则执行它 (对于我们的例子,假设该文件包含一些额外的功能。) 如果该文件不是普通文件,那么将发送消息说明,如果初始失败,那TERMTYPE变量为空,将发送另一个消息 2. 写一段脚本,有两个参数,将它们相乘并输出结果 expr $1 \* $2