语句结构
for 变量名 in 取值列表
do
命令序列
done
语句结构举例
for 收件人 in 邮件地址列表
do
发送邮件
done
添加需求描述:
[root@localhost ~]# vim /opt/users.txt
tom
zhangsan
lisi
wangwu
[root@localhost ~]# vim users.sh
#!/bin/bash
#定义
list=`cat /opt/users.txt`
#遍历集合
for user in $list
do
#添加用户
useradd $user
#设置密码
echo "123456" |passwd --stdin $user
echo "设置${user}用户成功"
done
[root@localhost ~]# sh users.sh
更改用户 tom 的密码 。
passwd:所有的身份验证令牌已经成功更新。
设置tom用户成功
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新。
设置zhangsan用户成功
更改用户 lisi 的密码 。
passwd:所有的身份验证令牌已经成功更新。
设置lisi用户成功
更改用户 wangwu 的密码 。
passwd:所有的身份验证令牌已经成功更新。
设置wangwu用户成功
删除需求描述:
[root@localhost ~]# vim users.sh
#!/bin/bash
#定义
list=`cat /opt/users.txt`
#遍历集合
for user in $list
do
#删除用户
userdel $user
#设置密码
#echo "123456" |passwd --stdin $user
echo "删除${user}用户成功"
done
[root@localhost ~]# sh users.sh
删除tom用户成功
删除zhangsan用户成功
删除lisi用户成功
删除wangwu用户成功
需求描述:
[root@localhost opt]# vim hosts.txt
20.0.0.1
192.168.100.100
20.0.0.2
[root@localhost opt]# vim pingip.sh
#!/bin/bash
#定义集合
list=`cat /opt/hosts.txt`
#遍历集合
for IP in $list
do
ping -c 3 -i 0.2 -W 3 $IP > /dev/null
#条件判断
if [ $? -eq 0 ];then
echo "$IP is on"
else
echo "$IP is down"
fi
done
[root@localhost opt]# sh pingip.sh
20.0.0.1 is down
192.168.100.100 is down
20.0.0.2 is on
#!/bin/bash
for ((i=1;i<=10;i++))
do
echo "$i"
done
#!/bin/bash
i=1
for ((;i<=10;i++))
do
echo "$i"
done
#!/bin/bash
i=1
for ((;i<=10;))
do
echo "$i"
let i++ done
#!/bin/bash
i=1
for ((;;))
do
if [ $i -le 10 ];then
echo "$i"
let i++
else
exit 0
fi
done
[root@localhost opt]# ./number.sh
1
2
3
4
5
6
7
8
9
10
let 对整数进行数学运算
let和双小括号 (( )) 一样,let 命令也只能进行整数运算,不能对小数(浮点数)或者字符串进行运算。
语法格式
let 表达式
或
let "表达式"
或
let '表达式'
以上方式都等价于 ((表达式))
" "
或者单引号' '
将表达式包围起来。方式一:计算偶数的和
#!/bin/bash
sum=0
#循环
for ((i=0;i<=10;i+=2))
do
let sum+=$i
done
echo "和为:${sum}"
[root@localhost opt]# sh oushuhe.sh
和为:30
计算奇数的和
#!/bin/bash
sum=0
#循环
for ((i=1;i<=10;i+=2))
do
let sum+=$i
done
echo "和为:${sum}"
[root@localhost opt]# sh oushuhe.sh
和为:25
方式二:求偶数和
#!/bin/bash
sum=0
for((i=0;i<=10;i+=2))
do
if [ `expr $i % 2` -eq 0 ]
then
let sum+=$i
fi
done
echo "总和为:$sum"
求奇数和
#!/bin/bash
sum=0
for((i=1;i<=10;i+=2))
do
if [ `expr $i % 2` -eq 1 ]
then
let sum+=$i
fi
done
echo "总和为:$sum"
语句结构
while 条件测试操作
do
命令序列
done
语句结构示例
while 未猜中正确的价格
do
反复猜测商品价格
done
#!/bin/bash
i=0
while [ $i -le 10 ]
do
echo "$i"
let i++
done
[root@localhost opt]# sh oushuhe.sh
0
1
2
3
4
5
6
7
8
9
10
while true:死循环有时候也有奇效,可与用户交互
[root@localhost opt]# vim sixunhuan.sh
#!/bin/bash
while true
do
read -p "输入yes继续/no退出:" way
if [ $way = no ];then
break
fi
done
echo "正常退出"
[root@localhost opt]# sh sixunhuan.sh
输入yes继续/no退出:yes
输入yes继续/no退出:yse
输入yes继续/no退出:no
正常退出
需求描述:
[root@localhost opt]# vim stu.sh
#!/bin/bash
i=1
while [ $i -le 20 ]
do
useradd stu$i
echo "123456" | passwd --stdin stu$i &> /dev/null
echo "设置stu${i}用户成功"
let i++
done
[root@localhost opt]# sh stu.sh
设置stu1用户成功
设置stu2用户成功
设置stu3用户成功
设置stu4用户成功
设置stu5用户成功
设置stu6用户成功
设置stu7用户成功
设置stu8用户成功
设置stu9用户成功
设置stu10用户成功
设置stu11用户成功
设置stu12用户成功
设置stu13用户成功
设置stu14用户成功
设置stu15用户成功
设置stu16用户成功
设置stu17用户成功
设置stu18用户成功
设置stu19用户成功
设置stu20用户成功
[root@localhost opt]# vim price.sh
#!/bin/bash
price=`expr $RANDOM % 100`
i=0
while true
do
read -p "请输入你认为的价格(1~100):" num
let i++
if [ $num -eq $price ];then
echo "恭喜你,猜对了"
echo "你输入的次数为:$i"
break
elif [ $num -gt $price ];then
echo "高了"
continue
else
echo "低了"
continue
fi
done
[root@localhost opt]# sh price.sh
请输入你认为的价格(1~100):50
低了
请输入你认为的价格(1~100):75
高了
请输入你认为的价格(1~100):65
高了
请输入你认为的价格(1~100):55
低了
请输入你认为的价格(1~100):60
低了
请输入你认为的价格(1~100):63
高了
请输入你认为的价格(1~100):62
恭喜你,猜对了
你输入的次数为:7
命令格式
continue n
n 表示循环的层数:
如果省略 n,则表示 continue 只对当前层次的循环语句有效,遇到 continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
如果带上 n,比如 n 的值为 2,那么 continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带 n 的 continue。这么说可能有点难以理解,稍后我们通过代码来演示。
continue 关键字也通常和 if 语句一起使用,即满足条件时便跳出循环。
命令格式
break n
n 表示跳出循环的层数,如果省略 n,则表示跳出当前的整个循环。
break 关键字通常和 if 语句一起使用,即满足条件时便跳出循环。
break 用来结束所有循环,循环语句不再有执行的机会;continue 用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环;exit用来突出应用程序。
需求描述:
[root@localhost opt]# vim name.txt
1:zhangsan
2:lisi
3:wangwu
[root@localhost opt]# vim choujiang.sh
#!/bin/bash
B=0
C=0
D=0
for ((i=1;i<=10;i++))
do
A=$(expr $[RANDOM%3+1])
list=$(cat /opt/name.txt|grep "$A" |awk -F: '{print $2}')
case $list in
zhangsan)
let B++
;;
lisi)
let C++
;;
*)
let D++
esac
echo "$list"
done
[root@localhost opt]# sh choujiang.sh
zhangsan
lisi
wangwu
lisi
zhangsan
lisi
wangwu
zhangsan
wangwu
wangwu
重复测试某个条件,只要条件不成立则反复执行
until 条件测试操作
do
命令序列
done
while 未超过 10
do
数字依次增加
done
示例一:计算1–50的和
需求描述:
[root@localhost opt]# vim he.sh
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]
do
let sum+=$i
let i++
done
echo $sum
[root@localhost opt]# sh he.sh
1275
示例二:为指定用户发送在线消息
需求描述:
分析:
1.位置参数个数大于1
2.姓名属于系统用户 /etc/passwd
3.用户是否在线 until who
4.发送消息 echo"消息" | write 用户名
[root@localhost opt]# vim xiaoxi.sh
#!/bin/bash
username=$1
#格式参数不能为空
if [ $# -lt 1 ];then
echo "Usage:`basename $0` []"
exit 1
fi
#验证是否属于系统用户
if grep "^$username" /etc/passwd > /dev/null;then :
else
echo "no user"
exit 2
fi
#测试用户是否在线,如果不在线,每5s联系一次
until who | grep "$usrename" > /dev/null
do
echo "user not login"
sleep 5
done
#发送消息
echo "$2" | write "$username"
echo "${username}发送成功"
[root@localhost opt]# sh xiaoxi.sh kevin hello
kevin发送成功
shell一个非常重要的特性是它可作为一种编程语言来使用。
因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这些程序时对它们进行解释。而程序的加载和解释都是非常耗时的。
针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。
shell还以一种内部格式来存放这些函数,这样就不必耗费大量的时间来解释它们
shell函数将命令序列按格式写在一起
可以方便重复使用命令序列
[ function ] 函数名(){
命令序列
[return x] 使用return或exit可以显式地结束函数
}
其中,return返回的是状态码,需要使用$?调取
echo 返回的是值,使用变量调用
传参:指位置变量
可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
函数名 [参数1($1)] [参数2($2)]
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
10不能获取第十个参数,获取第十个参数需要10 不能获取第十个参数,获取第十个参数需要10不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数。
示例
函数内部变量通过local来实现
#!/bin/bash
#求和函数体
function sum(){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$(($num1+$num2))
#echo 返回的是处理结果值
local score=100
echo "函数内$score"
echo "和:$SUM"
}
sum
echo "函数外$score"
示例一:两个数字求和
需求描述:
[root@localhost opt]# vim he.sh
#!/bin/bash
function sum(){
read -p "请输入第一个数字:" num1
read -p "请输入第二个数字:" num2
SUM=$[${num1}+${num2}]
echo "和为:$SUM"
}
sum
[root@localhost opt]# sh he.sh
请输入第一个数字:10
请输入第二个数字:20
和为:30
示例二:编写登陆系统后便可使用的用户自定义函数
需求描述:
编辑用户自定义函数文件/root/function
在当前ShelIl中加载可执行的函数文件/root/function
在~/.bashrc文件中添加source /root/function命令
[root@localhost ~]# vim ~/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
function sum(){
#命令序列
read -p "请输入第一个整数:" num1
read -p "请输入第二个整数:" num2
SUM=$[$num1+$num2]
#echo返回的是处理结果值
echo "和:$SUM"
[root@localhost ~]# source ~/.bashrc
[root@localhost ~]# sum
请输入第一个整数:10
请输入第二个整数:320
和:330
函数名称 参数1 参数2 参数3 …
$1 $2 3....... 3 ....... 3.......{10} ${11}…
示例:递归遍历目录
需求描述:
[root@localhost opt]# vim files.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 opt]# sh files.sh
anaconda
anaconda.log
ifcfg.log
journal.log
ks-script-E3s5jr.log
packaging.log
program.log
storage.log
syslog
X.log
audit
audit.log
boot.log
boot.log-20200609
boot.log-20200610
boot.log-20200611
boot.log-20200719
boot.log-20200720
boot.log-20200721
boot.log-20200722
btmp
btmp-20200719
chrony
cron
cron-20200609
cron-20200719
......
使用for循环获取具体信息,使用下标或索引标记数组中数据的位置
可以存放多种数据,如:整型,长整形,浮点型(单精度,双精度),字符串等
获取元素长度
遍历元素
元素切片
元素替换
元素删除
…
注意,忌讳数组越界,
数组下标从0开始算
数组长度从1开始算
长度为4,数组长度表示为1,2,3,4;数组下标表示为0,1,2,3
shell中数组是可变长的
方法一:(推荐)
基本格式
数组名=(value0 value1 value2…)
例如
ABC=(11 22 33…)
方法二:
基本格式
数组名=([0]=value [1]=value [2]=value…)
例如
ABC=([0]=11 [1]=22 [2]=33…)
方法三:数组元素之间使用空格隔开
基本格式
列表名=“value0 value1 value2” 数组名=($列表名)
例如
AAA=“11 22 33…”
ABC=($列表名)
方法四:(多用于替换)
基本格式
数组名[0]=“value”
数组名[1]=“value”
数组名[2]=“value” …
例如 AAA[0]=“11”
AAA[1]=“22”
AAA[2]=“33”
…
数值类型
字符类型
数组只可存放数值或字符
基本格式
${#数组名[@/*]}
例如
[root@localhost opt]# abc=(10 20 30)
[root@localhost opt]# echo ${abc[*]}
10 20 30
[root@localhost opt]# echo ${#abc[*]}
3
基本格式
${数组名[下标]}
例如
[root@localhost opt]# echo ${abc[1]}
20
[root@localhost opt]# echo ${abc[0]}
10
[root@localhost opt]# echo ${abc[1]}
20
[root@localhost opt]# echo ${abc[2]}
30
数组遍历
[root@localhost opt]# for v in ${arr_number[@]}
> do
> echo $v
> done
>
> 1
>
> 2
>
> 3
>
> 4
>
> 5
示例一:创建存放1~100奇数的数组
[root@localhost opt]# vim a.sh
#!/bin/bash
j=0
k=1
for ((i=0;i<=99;i++))
do
j=$[$i+$k]
let k++
if [ $j -lt 100 ];then
arr[$i]=$j
fi
done
echo ${arr[*]}
[root@localhost opt]# sh a.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 true
do
read -p "请输入第$[$i+1]元素:" j
arr[$i]=$j
read -p "请输入y/n:" guess
if [ $guess = y ];then
let i++
else
break
fi
done
echo ${arr[*]}
示例三:全班学生成绩未达到60分的,通过数组加到60分
#!/bin/bash
score=(48 59 60 68 90 78 86 56 98 56)
j=0
for ((i=0;i<${#score[*]};i++))
do
if [ ${score[$i]} -lt 60 ];then
new[$j]=60
else
new[$j]=${score[$i]}
let j++
fi
done
echo ${new[*]}
[root@localhost opt]# sh score.sh
60 68 90 78 86 98 60
示例四:根据示例三中分数,比较出最大值
#!/bin/bash
score=(48 59 60 68 90 78 86 56 98 56)
temp=0
for ((i=0;i<${#score[*]};i++))
do
if [ ${score[$i]} -gt $temp ];then
temp=${score[$i]}
fi
done
echo $temp
[root@localhost opt]# sh score.sh
98
示例五:根据示例三进行排序,由低到高
方法一:对比下标
#!/bin/bash
score=(48 59 60 68 90 78 86 56 98 56)
temp=0
for ((i=0;i<${#score[*]};i++))
do
for ((j=$i+1;j<${#score[*]};j++))
do
if [ ${score[$i]} -gt ${score[$j]} ];then
temp=${score[$i]}
let score[$i]=${score[$j]}
let score[$j]=temp
fi
done
done
echo ${score[*]}
方法二:找相对关系
#!/bin/bash
score=(48 59 60 68 90 78 86 56 98 56)
#外层为轮
for ((i=1;i<${#score[*]};i++))
do
#内存为次
for ((j=0;j<${#score[*]}-i;j++))
do #两数交换
if [ ${score[$j]} -gt ${score[`expr $j + 1` ]} ];then
tem=${score[`expr $j + 1`]}
score[`expr $j + 1`]=${score[$j]}
score[$j]=$tem
fi
done
done
echo ${score[*]}
[root@localhost opt]# sh score.sh
48 56 56 59 60 68 78 86 90 98
- echo命令
- bash命令
命令语法
sh [-nvx] 脚本名
常用选项
-n:不执行
-v:输出
-x:执行