一、循环语句 1、for循环详解 for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理。当要处理的数据有范围时, 使用for循环语句就再适合不过了。
读取不同的变量值,用来逐个执行同一组命令
语法: for 变量名 in 取值列表 do 命令序列(命令行) done
示例1: 下面使用for循环语句从列表文件中读取多个用户,然后为其逐一创建用户账户并设置密码。 首先创建用户名称的列表文件users.txt,每个用户名称单独一行。
1 2 3 4 5 6 [root@node1 ~] marry tom rose mike
接下来编写shell标本addusers.sh。在脚本中使用read命令读取用户输入的密码值,然后赋值给PASSWD 变量,并通过-p参数向用户显示一段提示信息,告诉用户正在输入的内容即将作为账户密码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@node1 ~] read -p "enter the user password:" PASSWD for UNAME in `cat /root/user.txt`do useradd $UNAME echo "$PASSWD" | passwd --stdin $UNAME echo "$UNAME" ,create success done [root@node1 ~] [root@node1 ~] enter the user password:redhat Changing password for user marry. passwd: all authentication tokens updated successfully. marry,create success Changing password for user tom. passwd: all authentication tokens updated successfully. tom,create success Changing password for user rose. passwd: all authentication tokens updated successfully. rose,create success Changing password for user mike. passwd: all authentication tokens updated successfully. mike,create success
示例2: 循环输出1-10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@node1 ~] for ((i=1 ;i<=10 ;i++)) do echo $i done [root@node1 ~] [root@node1 ~] 1 2 3 4 5 6 7 8 9 10
示例3: 用for语句,输出1-100的所有整数和
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@node1 ~] a=0 for ((i=1 ;i<=100 ;i++))do a=$(($a+$i)) done echo "1-100所有整数相加的和未$a" [root@node1 ~] [root@node1 ~] 1 -100 所有整数相加的和未5050
示例4: 根据IP地址检测主机状态 主机列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@node1 ~] 192.168 .100 .112 192.168 .100 .114 192.168 .100 .115 [root@node1 ~] ip=$(cat /root/iplist) for i in $ipdo ping -c 3 $i &>/dev/null if [ $? -eq 0 ];then echo "$i通" else echo "$i不通" fi done [root@node1 ~] [root@node1 ~] 192.168 .100 .112 通192.168 .100 .114 通192.168 .100 .115 不通
2、while语句 重复测试某个条件,只要条件成立,则反复执行
示例1: 显示0-10的所有整数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [root@node1 ~] a=0 while [ $a -le 10 ]do echo $a let a++ done [root@node1 ~] [root@node1 ~] 0 1 2 3 4 5 6 7 8 9 10
示例2: 求1-100的整数和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@node1 ~] i=0 n=1 while [ $n -le 100 ]do i=$(( $i + $n )) let n++ done echo "1-100的和为:$i" [root@node1 ~] [root@node1 ~] 1 -100 的和为:5050
随机数
1 2 3 4 5 6 7 8 9 [root@node1 ~] 5 [root@node1 ~] 36 [root@node1 ~] 47 [root@node1 ~] 22
示例3: 随机猜数字游戏,1000以内的猜数字游戏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 [root@node1 ~] num=$(expr $RANDOM % 1000 ) a=0 echo "数字范围为0-999的整数,猜猜看" while truedo read -p "请输入你猜的整数:" n let a++ if [ $n -eq $num ];then echo "恭喜你答对了,数字为$num" echo "你总共猜了$a次" exit 0 elif [ $n -gt $num ];then echo "你猜高了" else echo "你猜低了" fi done [root@node1 ~] [root@node1 ~] 数字范围为0 -999 的整数,猜猜看 请输入你猜的整数:500 你猜高了 请输入你猜的整数:250 你猜低了 请输入你猜的整数:350 你猜高了 请输入你猜的整数:300 你猜低了 请输入你猜的整数:325 你猜高了 请输入你猜的整数:310 你猜低了 请输入你猜的整数:317 你猜低了 请输入你猜的整数:322 你猜高了 请输入你猜的整数:320 恭喜你答对了,数字为320 你总共猜了9 次
3、until语句 重复测试某个条件,只要条件不成立,则反复执行
示例1: 求1-100的整数和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@node1 ~] a=0 for i in {1. .100 }do a=$((a + i)) done echo "1-100的整数和为: $a" [root@node1 ~] [root@node1 ~] 1 -100 的整数和为: 5050
4、双for循环 即在一个for循环内部再加一个for循环
1 2 3 4 5 6 7 8 9 for ((a=1 ;a<=5 ;a++))do echo "a=$a" for ((b=1 ;b<=5 ;b++)) do echo "b=$b" done done
示例:九九乘法表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@node1 ~] for (( a=1 ;a<10 ;a++ ))do for (( b=1 ;b<=a;b++ )) do echo -en "$b*$a=$(($a*$b))\t" done echo done [root@node1 ~] [root@node1 ~] 1 *1 =1 1 *2 =2 2 *2 =4 1 *3 =3 2 *3 =6 3 *3 =9 1 *4 =4 2 *4 =8 3 *4 =12 4 *4 =16 1 *5 =5 2 *5 =10 3 *5 =15 4 *5 =20 5 *5 =25 1 *6 =6 2 *6 =12 3 *6 =18 4 *6 =24 5 *6 =30 6 *6 =36 1 *7 =7 2 *7 =14 3 *7 =21 4 *7 =28 5 *7 =35 6 *7 =42 7 *7 =49 1 *8 =8 2 *8 =16 3 *8 =24 4 *8 =32 5 *8 =40 6 *8 =48 7 *8 =56 8 *8 =64 1 *9 =9 2 *9 =18 3 *9 =27 4 *9 =36 5 *9 =45 6 *9 =54 7 *9 =63 8 *9 =72 9 *9 =81
5、break和continue 在内循环执行break 就跳出当前的内循环了,去执行外循环了 作用: 1跳出当前循环 2并且break下面的语句不去执行
(1)break,我们可以通过内外循环的输出来看break的特性。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 [root@node1 ~] for (( a=1 ;a<=5 ; a++ ))do echo "outside $a" for ((b=1 ;b<=5 ;b++ )) do if [ $b -eq 4 ] then break fi echo "inside $b " done done [root@node1 ~] [root@node1 ~] outside 1 inside 1 inside 2 inside 3 outside 2 inside 1 inside 2 inside 3 outside 3 inside 1 inside 2 inside 3 outside 4 inside 1 inside 2 inside 3 outside 5 inside 1 inside 2 inside 3 内循环到4 就停止了,5 就不去判断了
(2)continue 中止某次循环,不会完全终止整个命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@node1 ~] for (( a=1 ;a<=15 ;a++))do if [ $a -gt 5 ] && [ $a -lt 10 ] then continue fi echo " $a " done [root@node1 ~] [root@node1 ~] 1 2 3 4 5 10 11 12 13 14 15
二、函数 将命令序列按格式写在一起 可重复使用命令序列
1、shell函数定义格式 1 2 3 4 5 6 7 8 9 10 11 12 13 function 函数名{ 命令序列 } 函数名(){ 命令序列 }
2、函数返回值 return return 表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值(0-255) 原则: 1.函数已结束就取返回值,因为 $? 只是对最后一条命令进行判断 2.0-255,超出时 除以256取余 echo也能直接返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@node1 ~] function sq { read -p "请输入任意一个整数值:" n return $[$n*2 ] } sq echo "$?" [root@node1 ~] [root@node1 ~] 请输入任意一个整数值:20 40 [root@node1 ~] 请输入任意一个整数值:30 60
3、函数传参 函数变量的作用范围(局部变量以及全局变量) 函数在shell脚本中仅在当前shell环境中有效 shell脚本中变量默认全局有效 将变量限定一个函数的内部local,即局部变量
(1)传参 1 2 3 4 5 6 7 8 9 10 11 [root@node1 ~] sum1 () { sum =$[ $1 + $2 ] echo $sum } sum1 $1 $2 [root@node1 ~] [root@node1 ~] 50
(2)变量的局部与全局 将变量限定在函数内部使用local命令 即这个local的变量仅仅在当前的函数内有效,在别的函数中无效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 abc () { echo "函数内的未经过local的变量i值$i" local i i=6 echo "函数内的变量i值是$i" } i=9 abc echo "函数外面的变量i值是$i" [root@node1 ~] 函数内的未经过local的变量i值9 函数内的变量i值是6 函数外面的变量i值是9
(3)local的进击
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 abc () { echo "inside1 $i" let i++ local i i=8 echo "inside2 $i" } i=9 abc echo "outside $i" [root@node1 ~] inside1 9 inside2 8 outside 10
4、递归(调用自己) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function cy() { if [ $1 -eq 1 ];then echo 1 else local temp=$[ $1 - 1 ] local result=`cy $temp` echo $[ result * $1 ] fi } read -p "输入一个值:" vaule result=`cy $vaule` echo "阶乘的值为: $result" [root@node1 ~] 输入一个值:5 阶乘的值为: 120 [root@node1 ~] 输入一个值:3 阶乘的值为: 6
5、函数库 就是把一般脚本的主体执行代码和定义函数部分相互分离,把定义的函数部分集中放在同一个脚本中。 具体执行的时候,只需要直接进行调用函数集合的脚本文件即可。
这里我把加减乘除共4个函数,做了一个函数库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 [root@node1 ~] jia() { result=$[ $1 + $2 ] echo "$result" } jian() { result=$[ $1 - $2 ] echo "$result" } cheng() { result=$[ $1 * $2 ] echo "$result" } chu() { if [ $2 -ne 0 ];then result=$[ $1 / $2 ] echo "$result" else echo "除法中分母不能为0" fi } [root@node1 ~] . /root/ee.sh read -p "请输入第一个数字:" n read -p "请输入第二个数字:" m result1=`jia $n $m` result2=`jian $n $m` result3=`cheng $n $m` result4=`chu $n $m` echo "两数之和为: $result1" echo "两数之差为: $result2" echo "两数之积为: $result3" echo "两数之商为: $result4" [root@node1 ~] [root@node1 ~] 请输入第一个数字:5 请输入第二个数字:2 两数之和为: 7 两数之差为: 3 两数之积为: 10 两数之商为: 2