shell脚本——函数、数组
文章目录
-
shell脚本——函数、数组 - 一、util
- 二、函数
- 三、递归函数
- 四、数组
- 五、shell 脚本调试
一、util
重复测试某个条件,只要条件不成立就反复执行
格式
util [ 条件格式操作 ]
do
命令序列
done
案例一:1-50求和
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]
do
sum=$[$sum+$i]
let i++
done
echo "$sum"
验证
[root@localhost data]# sh util.sh
1275
[root@localhost data]#
案例二:指定用户发送信息
方法一
[root@localhost shell]# vim zhidingusr.sh
#!/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 "no user"
exit 2 //返回值用于验证,无太大意义
fi
#测试用户是否在线,如果不在线,每5s联系一次
until who | grep "$username" > /dev/null;do
echo "user not login"
sleep 5
done
#发送消息
echo "$2" | write "$username"
echo "${username}发送成功"
验证
[root@localhost ~]# sh zhidingusr.sh zhangsan iiop
zhangsan发送成功
方法二
[root@localhost shell]# vim zdjyonghu.sh
#!/bin/bash
read -p "请输入你要联系的用户名:" a
if grep $a /etc/passwd >/dev/null
then
echo "当前用户在系统中,正在测试是否在线"
if who | grep $a > /dev/null
then
read -p "该用户在线,输入消息:" b
echo $b | write $a
echo "消息:$b 发送成功"
else
echo "该用户不在线"
until who | grep $a > /dev/null
do
sleep 2
echo "正在尝试联系该用户"
done
read -p "该用户已上线,输入消息:" b
echo $b | write $a
echo "消息发送成功"
fi
else
echo "没有该用户"
fi
验证
[root@localhost shell]# sh zdjyonghu.sh
请输入你要联系的用户名:zhangsan
当前用户在系统中,正在测试是否在线
该用户不在线
正在尝试联系该用户
正在尝试联系该用户
正在尝试联系该用户
正在尝试联系该用户
^C
[root@localhost shell]# sh zdjyonghu.sh
请输入你要联系的用户名:zhangsan
当前用户在系统中,正在测试是否在线
该用户在线,输入消息:ueiox
消息:ueiox 发送成功
案例三:数值求和
[root@localhost shell]# vim hansu.sh
#!/bin/bash
#求和函数体
function sum (){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第一个整数:" num2
SUM=$[$num1+$num2]
#echo 返回的是处理结果值
echo $SUM
#return 返回的是状态码
return 100
}
number=`sum`
echo $?
echo $number
[root@localhost shell]# sh hansu.sh
请输入第一个整数:10
请输入第一个整数:20
100
30
二、函数
- 将命令序号按格式写在一起
- 可方便重复使用命令序列
- shell函数定义
格式
shell函数的定义
[ function ] 函数名(){
命令序列
[return x ]
}
调用函数参数的方法
函数名 [ 参数1 ] [ 参数2 ]
num=(11 22 33 44 55 66 77)
函数的长度表示 : num_length=${#num[*]}
案例一:两个数值求和
调用参数
#!/bin/bash
#求和函数体
function sum (){
#命令序列
#read -p "请输入第一个整数:" num1
#read -p "请输入第一个整数:" num2
SUM=$[$1+$2]
#echo 返回的是处理结果值
echo $SUM
#return 返回的是状态码
return 100
}
number=`sum 10 20`
echo $?
echo $number
验证
[root@localhost shell]# sh hansu.sh
请输入第一个整数:10
请输入第一个整数:20
100
30
案例二:全局变量和局部变量验证
- 函数内定义的local变量,只能在函数内使用。全局变量可以在全局使用。
- shell脚本默认变量是全局有效的。
- 用户环境变量 ~.bashrc _profile
- 系统环境变量 /etc/profile
#!/bin/bash
function sum(){
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$[$num1 + $num2]
local score=70
echo "$SUM"
echo "局部数值:$score"
}
sum
echo "全局数值:$score"
验证
[root@localhost shell]# vim local.sh
[root@localhost shell]# sh local.sh
请输入第一个整数:10
请输入第二个整数:30
40
局部数值:70
全局数值:
案例二:在用户环境变量文件中添加自定义函数并调用
[root@localhost ttyy]# vim .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
#!/bin/bash
function sum(){
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$[$num1 + $num2]
local score=70
echo "$SUM"
echo "局部数值:$score"
}
# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH
---------验证----------
[root@localhost ttyy]# source .bash_profile
[root@localhost ttyy]# sum
请输入第一个整数:10
请输入第二个整数:20
30
局部数值:70
三、递归函数
调用自己本身的函数
案例一:递归调用显示/var/log目录的所有文件
[root@localhost shell]# vim digui.sh
#!/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" ""
验证
[root@localhost shell]# sh digui.sh
anaconda
anaconda.log
ifcfg.log
journal.log
ks-script-RVBEet.log
packaging.log
program.log
storage.log
syslog
X.log
audit
audit.log
boot.log
boot.log-20200716
boot.log-20200717
boot.log-20200719
boot.log-20200720
boot.log-20200721
btmp
chrony
cron
cron-20200719
cups
access_log
access_log-20200719
error_log
page_log
dmesg
dmesg.old
firewalld
gdm
:0-greeter.log
:0-greeter.log.1
:0-greeter.log.2
:0-greeter.log.3
:0-greeter.log.4
:0.log
:0.log.1
:0.log.2
:0.log.3
:0.log.4
:1-greeter.log
:1.log
glusterfs
grubby_prune_debug
lastlog
libvirt
qemu
maillog
maillog-20200719
messages
messages-20200719
ntpstats
pluto
peer
ppp
qemu-ga
rhsm
sa
sa15
sa16
sa17
sa18
sa19
sa20
sa21
sar15
sar16
sar17
sar20
samba
old
secure
secure-20200719
speech-dispatcher
spooler
spooler-20200719
sssd
swtpm
libvirt
qemu
tallylog
tuned
tuned.log
vmware-network.1.log
vmware-network.2.log
vmware-network.3.log
vmware-network.4.log
vmware-network.5.log
vmware-network.6.log
vmware-network.7.log
vmware-network.8.log
vmware-network.9.log
vmware-network.log
vmware-vgauthsvc.log.0
vmware-vmsvc.log
vmware-vmusr.log
wpa_supplicant.log
wtmp
xferlog
Xorg.0.log
Xorg.0.log.old
Xorg.1.log
Xorg.9.log
yum.log
shell脚本数值取绝对值
四、数组
数组:相同类型数据的集合
[11,22,33,44] 在内存中开辟了连续的空间
配合循环使用
数组名称:arr arr=(11,22,33,44) 索引
0 1 2 3
数组元素: 11 22 33 44
数组的长度: 4
数组下标: 33元素的下标值是2
for 临时变量 in 数组
do
done
1. 数组的切片
格式
${数组名[@/*]:起始位置:长度}
案例
[root@localhost shell]# arr=(1 2 4 5)
[root@localhost shell]# echo ${arr[@]:1:3} //数组切片
2 4 5
[root@localhost shell]# echo ${arr[*]/4/99}
1 2 99 5
[root@localhost shell]# arr=(${arr[*]/4/99}) //从数组中替换
[root@localhost shell]# echo ${arr[*]}
1 2 99 5
[root@localhost shell]#
[root@localhost shell]# unset arr[3] //删除单个元素
[root@localhost shell]# echo ${arr[*]}
1 2 99
[root@localhost shell]#
[root@localhost shell]# unset arr //删除整个数组
[root@localhost shell]# echo ${arr[*]}
2. 数组的替换
格式
${数组名[@/*]/查找字符/替换字符}
3.数组的删除
unset
案例
五、shell 脚本调试
1. echo 命令
2. bash 命令
命令语法
sh [-nvx] 脚本名
常用选项
-n -v -x
[root@localhost shell]# sh -nvx bujigeshanchu.sh
#!/bin/bash
num=(56 76 67 55 32 10)
for (( i=0;i<=5;i++))
do
if [ ${num[$i]} -lt 60 ]
then
unset num[$i]
fi
done
echo ${num[*]}
[root@localhost shell]# sh -x bujigeshanchu.sh
+ num=(56 76 67 55 32 10)
+ (( i=0 ))
+ (( i<=5 ))
+ '[' 56 -lt 60 ']'
+ unset 'num[0]'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 76 -lt 60 ']'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 67 -lt 60 ']'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 55 -lt 60 ']'
+ unset 'num[3]'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 32 -lt 60 ']'
+ unset 'num[4]'
+ (( i++ ))
+ (( i<=5 ))
+ '[' 10 -lt 60 ']'
+ unset 'num[5]'
+ (( i++ ))
+ (( i<=5 ))
+ echo 76 67
76 67
[root@localhost shell]# sh -n bujigeshanchu.sh
[root@localhost shell]# sh -v bujigeshanchu.sh
#!/bin/bash
num=(56 76 67 55 32 10)
for (( i=0;i<=5;i++))
do
if [ ${num[$i]} -lt 60 ]
then
unset num[$i]
fi
done
echo ${num[*]}
76 67
3. set 命令
- set -x : 开启调节模式
- set +x : 关闭调节模式
***********方法一*****************
[root@localhost shell]# num=(11 22 33)
[root@localhost shell]# echo ${num[*]}
11 22 33
[root@localhost shell]# echo ${num[2]}
33
[root@localhost shell]# echo ${num[0]}
11
[root@localhost shell]#
***********方法二******************
[root@localhost shell]# num1=([0]=12 [1]=77 [2]=88 [3]=99)
[root@localhost shell]# echo ${num1[@]}
12 77 88 99
[root@localhost shell]# echo ${num[@]}
11 22 33
[root@localhost shell]# echo ${num1[*]}
12 77 88 99
[root@localhost shell]#
************方法三******************
[root@localhost shell]# num2="11 22 33 44"
[root@localhost shell]# num=($num2)
[root@localhost shell]# echo ${num[*]}
11 22 33 44
[root@localhost shell]#
案例一:输出数组100元素
#!/bin/bash
for (( i=0;i<=99;i++))
do
num[$i]=$[$i+1]
done
echo ${num[*]}
验证
[root@localhost shell]# sh shuzu.sh
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
[root@localhost shell]#
案例二:输出奇数数组
[root@localhost shell]# vim jisu.sh
#!/bin/bash
k=0
j=1
for (( i=0;i<=99;i++ ))
do
k=$[$i+$j]
let j++
if [ $k -le 100 ];then
num[$i]=$k
fi
done
echo ${num[*]}
验证
[root@localhost shell]# sh jisu.sh
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99
案例三:输入任意长度的数字,任意的长度的数组。
方法一
在这里插入代码片
在这里插入代码片
方法二
#!/bin/bash
i=0
while [ 1 ];do
if [ $i != 0 ];then
read -p "是否继续输入y/n?" is
if [ $is = "n" ];then
break
fi
fi
read -p "请输入新数据元素?" num
sum[$i]=$num
let i++
done
echo ${sum[*]}
验证
请输入新数据元素?32
是否继续输入y/n?y
请输入新数据元素?5
是否继续输入y/n?y
请输入新数据元素?3
是否继续输入y/n?n
32 5 3
案例四:将小于60的分数,变为60
方法一
[root@localhost shell]# vim bujige.sh
#!/bin/bash
num=(56 76 67 55 32 87)
for (( i=0;i<=5;i++))
do
if [ $[num[$i]] -lt 60 ]
then
num[$i]=60
fi
done
echo ${num[*]}
验证
[root@localhost shell]# sh bujige.sh
60 76 67 60 60 87
方法二
#!/bin/bash
num=(56 76 67 55 32 87)
for (( i=0;i<${#num[*]};i++))
do
if [ ${num[$i]} -lt 60 ]
then
num[$i]=60
fi
done
echo ${num[*]}
验证
[root@localhost shell]# sh bujige.sh
60 76 67 60 60 87
案例五:输出最大值
#!/bin/bash
num=(89 30 40 76 100)
max=0
for (( i=0;i<${#num[*]};i++))
do
if [ ${num[$i]} -gt $max ]; then
max=${num[$i]}
fi
done
echo $max
验证
[root@localhost shell]# sh max-1.sh
100
案例六:插入法排序-升序
[root@localhost shell]# vim sort.sh
#!/bin/bash
a=(98 23 45 67 7 8 99)
k=${#a[*]}
for (( i=1;i<$k;i++ ))
do
if [ ${a[$i]} -lt ${a[$i-1]} ]
then
let temp=${a[$i]} ////保存要比较的值
for (( j=$i-1; j>=0;j--))
do
if [ ${a[j]} -gt $temp ] ////从后向前查找待插入位置
then
let a[$j+1]=a[$j] //挪位
else
break
fi
done
let a[$j+1]=$temp ////复制到插入位置
fi
done
echo ${a[*]}
**验证**
[root@localhost shell]# sh sort.sh
7 8 23 45 67 98 99
案例七:插入法排序-降序
#!/bin/bash
a=(98 23 45 67 7 8 99)
k=${#a[*]}
for (( i=1;i<$k;i++ ))
do
if [ ${a[$i]} -gt ${a[$i-1]} ]
then
let temp=${a[$i]}
for (( j=$i-1; j>=0;j--))
do
if [ ${a[j]} -lt $temp ]
then
let a[$j+1]=a[$j]
else
break
fi
done
let a[$j+1]=$temp
fi
done
echo ${a[*]}
验证
[root@localhost shell]# sh sort.jiaxu.sh
99 98 67 45 23 8 7
案例八:冒泡法排序
[root@localhost shell]# vim sort-maopao.sh
#!/bin/bash
a=(55 66 11 33 99)
k=${#a[*]}
for ((i=0;i<$k;i++))
do
temp=1
for (( j=1;j<=$[$k-$i];j++ ))
do
if [ ${a[$j]} -lt ${a[$j-1]} ]
then
tem=${a[$j]}
a[$j]=${a[$j-1]}
a[$j-1]=$tem
temp=0
fi
done
if [ $temp -eq 1 ]
then
break
fi
done
echo ${a[*]}
**********验证**********
[root@localhost shell]# sh sort-maopao.sh
11 33 55 66 99
案例九:删除数组中小于60的数值
[root@localhost shell]# vim bujigeshanchu.sh
#!/bin/bash
num=(56 76 67 55 32 87)
for (( i=0;i<${#num[*]};i++))
do
if [ ${num[$i]} -lt 60 ]
then
unset num[$i]
fi
done
echo ${num[*]}
*********验证*****************
[root@localhost shell]# sh bujigeshanchu.sh
76 67 32 87
方法二