理论+实验·Shell编程之循环语句、函数、数组

理论+实验·Shell编程之循环语句、函数、数组

for语句的结构

读取不通的变量值,用来逐个执行同一组命令

for 变量名 in 取值列表  ===>变量名是临时变量名从取值列表里面去读

do

​    命令序列

done

for语句应用实例

示例一

批量添加用户

用户名存放在user.txt文件中,每行一个

初始化密码均设为123456

验证脚本

#!/bin/bash
#定义集合
list=`cat /opt/users.txt`
#遍历创建新用户
for user in $list
do
	#创建新用户
	useradd $user
	#设置密码
	echo "123456" | passwd --stdin $user
	echo "$user创建成功"
done

示例二

根据IP地址检查主机状态

IP地址存放在ipadds.txt文件中,每行一个

使用ping命令检测各主机的连通性

#!/bin/bash
#定义集合
ip_=`cat /opt/ipadds.txt`
#遍历
for ipaddress in $ip_
do
	#pingIP地址
	ping -c 3 -i 0.2 -W 3 $ipaddress &>/dev/null	===>-c 次数 -i 间隔多久在ping一次 -W 等待时间
	if [ $? -eq 0 ];then
	echo "${ipaddress} is up"
	else echo "${ipaddress} is down"
	fi
done

常用变量

变量i=1

i<=10 

i++ 自身加1

((;;)) ===>没有条件无限循环

break  ===>退出当前循环

exit 0  ===>退出应用程序,后面的所有语句都不会执行

exit 0 ===>0是状态码  0 表示正常退出
(1-100)偶数和
#!/bin/bash
sum=0
for ((i=1;i<=100;i++))
do
	#条件筛选
	if [ `expr $i % 2` -eq 1 ];then
	let sum=${sum}+${i}
	fi
done
echo "${sum}"
(1-100)奇数和
#!/bin/bash
sum=0
for ((i=1;i<=100;i+=2))
do
let sum+=$i
done
echo "$sum"
++	===>自身变量+1    

--	===>自身变量-1    let可以单独使用

+=5 	===>自身变量+5

-=5	===>自身变量*5

\*=5	===>自身变量乘以5

/=5	===>自身变量除以5

%=5	===>自身变量%5

((;;))	无限循环

$() 	===> ``	命令替换

[ ]	===>test	条件判断

$[ ]	===> $(( ))	算术运算

${}	变量替换

(())	===>	支持数学运算符的 条件判断

while语句的结构

重复测试某个条件,只要条件成立则反复执行

while 条件测试操作
do
  命令序列
done

只要成立会一直不停的执行下去

while语句应用实例

示例一

批量添加用户

用户名称以stu开头,按数组顺序进行编号

一共添加20各用户,即stu1,stu2,stu3…stu20

从初始密码均设为123456

#!/bin/bash
i=1
user=stu$i
while [ $i -le 20 ]
do
  echo stu$i
  useradd stu$i
  echo "123456" | passwd --stdin $user
  echo "用户${user}输出成功"
  let i++
done

示例二

猜商品价格游戏

通过变量RANDOM获得随机数

提示用户猜测并记录次数,猜中后退出循环

#!/bin/bash

#假设商品价格为60元
read -p "请猜出商品的价格(元):" howmuch
while [ $howmuch -ne 60 ];do
	echo "离商品价格还有一点距离"
	read -p "请重新猜出商品的价格(元):" howmuch
done
	echo "恭喜您猜对了,商品价格为$howmuch"

coutinue 跳过本次continue以下执行语句直接进入下一次循环

break 退出当前循环语句

exit 1 直接退出不执行下面的语句

双重循环示例

九九乘法口诀表

#!/bin/bash
i=1
while [ $i -le 9 ]
do
        j=1
        while [ $j -le $i ]
        do
        echo -n "${i}*${j}"="`expr ${i} \* ${j}`	"
        let j++
        done
echo ""
let i++
done

等腰三角形

#!/bin/bash
read -p "请输入行数:" num
i=1
while [ $i -le $num ]
do
        j=${num}
        while [ $j -ge $i ]
        do
        echo -n " "
        let j--
        done

        k=1
        while [ $k -le $i ]
        do
        echo -n "* "
        let k++
        done
echo ""
let i++
done

until语句的结构

重复测试某个条件,只要条件不成立则反复执行

until	条件测试操作

do

		命令序列

done

until语句应用实例

示例一

计算1~50的和值

通过循环累加的方式计算1-50的和值

#!/bin/bash

i=1

sum=0

until [ $i -eq 51 ]

do

        \#echo $i

        let sum+=$i

        let i++

done

echo "和为:$sum"

示例二

为指定用户发送在线消息

若用户不在线(未登录系统),则每10分钟试一次,直至用户登录系统后在发送信息

用户名与信息通过位置参数传递给脚本

#!/bin/bash

username=$1

#格式参数不能为空

if [ $# -lt 1 ];then

echo "Usage:'basename $0' <username> [<message>]"

exit 1

fi

#验证是否属于系统用户

if grep "^$username" /etc/passwd > /dev/null;then空格:

else

echo "not user"

exit 2

fi

#测试用户是否在线,如果不在线,每5秒联系一次

until who | grep "$username" > /dev/null;do

echo "user not login"

sleep 5

done

#发送消息

echo "$2" | write "$username"

echo "${username}发送成功"

Shell函数

将命令序列按格式写在一起

可方便重复使用命令序列

Shell函数定义

[ function ] 函数名(){

命令序列

[return x]	===>返回的状态码  $?	
				返回数据 echo输出
}

调用函数的方法

函数名 [参数1] [参数2]

函数应用实例

示例一

两个数字求和

通过sum (){} 定义函数

使用read命令交互输入两个数并求和

#!/bin/bash

function sum(){

#命令序列

read -p "请输入第一个整数:" num1

read -p "请输入第二个整数:" num2

SUM=$[${num1}+${num2}]

#echo返回的是处理结果值

echo "和为:$SUM"

#return返回的是状态码

return 100

}

sum

示例二

编写登录系统后便可使用的用户自定义函数

编辑用户自定义函数文件/root/function

在当前Shelll中加载可执行的函数文件/root/function

在~/.bashrc文件中添加source /root/function命令

[root@localhost opt]# vim /root/.bashrc 

......

function sum(){

#命令序列

read -p "请输入第一个整数:" num1

read -p "请输入第二个整数:" num2

SUM=$[${num1}+${num2}]

#echo返回的是处理结果值

echo "和为:$SUM"

#return返回的是状态码

return 100

}

[root@localhost opt]# source /root/.bashrc	===>重新加载以下配置文件

[root@localhost opt]# sum	===>直接调用

函数的作用范围

函数在Shell脚本中仅在当前Shell环境中有效

Shell脚本中变量默认全局有效

将变量限定在函数内部使用local命令

示例

函数内部变量通过local来实现

​ 通过定义myfun函数,在其内部设置局部变量i

​ 函数内部和外部分别赋值,进行结果验证

​ local score ===>加了local就是局部变量

函数的参数

参数的用法

函数名称参数1参数2多数…

参数的表示方法

$1 $2 $3… S(10} ${11} …

示例

通过函数参数将日志信息写入文件,

通过定义appendfile函数实现

递归函数

调用自己本身的函数

示例

递归遍历目录

​ 通过定义递归函数list_files来实现

#!/bin/bash

function list_files(){

       for f in `ls $1`    

       do  

         if [ -d "$1/$f" ];then

           echo "$2$f"

           #递归调用

           list_files "$1/$f" "  $2"

       else  

         echo "$2$f"

       fi

       done

}   

list_files "/var/log" ""

Shell数组

应用场景包括

获取数组长度

获取元素长度

遍历元素

元素切片 ===>某一个子部份

元素替换

元素删除

数组定义方法

方法一

数组名= (value0 value1 value2 ...)

方法二

数组名= ([0]=value [1]=value [2]=value ...)

方法三

列表名="value0 value1 value2"

数组名=($列表名)

方法四

数组名[0]="value"

数组名[1]="value"

数组名[2]="value"

数组包括的数据类型

数值类型

字符类型

​ 使用""或’'定义

#!/bin/bash

#创建存放(1-100)奇数的数组
for ((i=0,j=1;i<=99,j<=100;i++,j+=2))
do
  arr[$i]="$j"
done
echo ${arr[*]}
#!/bin/bash

#创建任意数字及长度的数组,根据客户的需求加入元素
i=0
while [ $i -ge 0 ]
do
read -p "请输入该数组的元素:" num
arr[$i]="$num"
let i++
        if [ -z $num ];then
        echo ${arr[*]}
        exit 1
        fi
done

Shellt数组操作

获取数组长度

$(数组名[@/]}

[root@localhost -# arr-number=(1 2 3 4 5);

[root@localhost -arr-length=$(#arr-number[*]}

root@localhost -]# echo $arr_length
5

读取某下标赋值

$(数组名[下表])

[root@localhost-arr-index2-$(arr-number[2])

[root@localhost-# echo $arr-index2
3

数组遍历

[root@localhost ~] # for v in $farr numberl@}
>do 
>echo $v
> done
1
2
3
4
5

示例

#!/bin/bash

#不满足60分的都加到60分
score=(66 58 49 60 88 96)
for ((i=0;i<=&{#score[*]};i++));do
	if [ ${score[$i]} -lt 60 ];then
		new[$i]=60
	else
		new[$i]=${score[$i]}
	fi
done
echo ${new[*]}
#!/bin/bash

#显示出最大的那个分数
score=(66 58 49 60 88 96)
tmp=0
for ((i=0;i<${#score[*]};i++));do
	if [ ${score[$i]} -gt $tmp ];then
		tmp=${score[$i]}
	fi
done
echo $tmp
#!/bin/bash

#将分数从大到小排序
arr=(85 100 56 69 75 98 65 45)
for ((i=0;i<${#arr[*]};i++))
do
   for ((j=$i+1;j<${#arr[*]};j++))
    do
        if [ ${arr[$i]} -lt ${arr[$j]} ];then
        tmp=${arr[$i]}
        arr[$i]=${arr[$j]}
        arr[$j]=$tmp
        fi
    done
done
echo ${arr[*]}

数组切片

${数组名[@或*]:起始位置:长度}

[root@centos-7-# arr=(1 2 3 4 5)

[root@centos-7-]# echo $farr[@])

1 2 3 4 5

[root@centos-7-]# echo $farr[@]:0:2}

1 2

root@centos-7 - echo $arr[@]:2:3}

3 4 5

数组的替换

${数组名[@或*]/查找字符/替换字符}

[root@centos-7 -]#arr=(1 2 3 4 5)

[root@centos-7-]# echo ${arr[@14/66}

12 3 66 5

[root@centos-7-]#echo $farr@])

1 2 3 4 5

[root@centos-7-# arr=($(arr[@]/4/66})

[root@centos-7 -]# echo $farr[@])

1 2 3 66 5

数组删除

unset

[root@centos-7 -# arr=(1 2 3 4 5)
[root@centos-7~#unset arr
[root@centos-7 -]# echo ${arr[*])

[root@centos-7- arr=(1 2 3 4 5)
[root@centos-7-#unset arr[2)
[root@centos-7-]# echo ${arr[*])
1 2 4 5

示例

#!/bin/bash



#将低于60分以下的成绩删除

score=(10 20 30 40 50 90 80 50 60)

i=1

for	f	in	${score[*]};do

	if	[ $f -lt 60 ];then

	  unset score[$i]

	fi

	lei i++

done

echo ${score[*]}

Shell脚本调试

echo命令

bash命令

命令语法

sh [-nvx] 脚本名

set命令

set -x:开启调节模式

set +x:关闭调节模式

猜你喜欢

转载自blog.csdn.net/weixin_47153668/article/details/107508878