目录
一 循环语句
1.1 for循环语句
[root@localhost ~]# vi /root/users.txt
chen
wen
jian
[root@localhost ~]# vi uaddfor.sh
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
useradd $UNAME
echo "123456" | passwd --stdin $UNAME &> /dev/null
done
[root@localhost ~]# chmod +x uaddfor.sh
[root@localhost ~]# ./uaddfor.sh
[root@localhost ~]# tail -3 /etc/passwd
chen:x:1001:1001::/home/chen:/bin/bash
wen:x:1002:1002::/home/wen:/bin/bash
jian:x:1003:1003::/home/jian:/bin/bash
[root@localhost ~]# vi /root/ipadds.txt
20.0.0.1
20.0.0.2
20.0.0.10
20.0.0.21
20.0.0.100
[root@localhost ~]# vi chkhosts.sh
#!/bin/bash
HLIST=$(cat /root/ipadds.txt)
for IP in $HLIST
do
ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
if [ $? -eq 0 ]
then
echo "Host $IP is up" && echo "Host $IP is up" >>/root/ipup.txt
else
echo "Host $IP is down" && echo "Host $IP is down" >>/root/ipdown.txt
fi
done
[root@localhost ~]# chmod +x chkhosts.sh
[root@localhost ~]# ./chkhosts.sh
Host 20.0.0.1 is up
Host 20.0.0.2 is up
Host 20.0.0.10 is down
Host 20.0.0.21 is up
Host 20.0.0.100 is down
[root@localhost ~]# ll
......
-rw-r--r-- 1 root root 49 Aug 13 09:17 ipadds.txt
-rw-r--r-- 1 root root 196 Aug 13 09:19 ipdown.txt
-rw-r--r-- 1 root root 224 Aug 13 09:19 ipup.txt
......
[root@localhost ~]# cat ipup.txt
Host 20.0.0.1 is up
Host 20.0.0.2 is up
Host 20.0.0.21 is up
[root@localhost ~]# cat ipdown.txt
Host 20.0.0.10 is down
Host 20.0.0.100 is down
1.2 while循环语句
[root@localhost ~]# vi usaddwhile.sh
#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 20 ]
do
useradd ${PREFIX}$i
echo "123456" | passwd --stdin ${PREFIX}$i &>/dev/null
let i++
done
[root@localhost ~]# chmod +x usaddwhile.sh
[root@localhost ~]# ./usaddwhile.sh
[root@localhost ~]# grep "stu" /etc/passwd
stu1:x:1001:1001::/home/stu1:/bin/bash
stu2:x:1002:1002::/home/stu2:/bin/bash
stu3:x:1003:1003::/home/stu3:/bin/bash
stu4:x:1004:1004::/home/stu4:/bin/bash
stu5:x:1005:1005::/home/stu5:/bin/bash
stu6:x:1006:1006::/home/stu6:/bin/bash
stu7:x:1007:1007::/home/stu7:/bin/bash
stu8:x:1008:1008::/home/stu8:/bin/bash
stu9:x:1009:1009::/home/stu9:/bin/bash
stu10:x:1010:1010::/home/stu10:/bin/bash
stu11:x:1011:1011::/home/stu11:/bin/bash
stu12:x:1012:1012::/home/stu12:/bin/bash
stu13:x:1013:1013::/home/stu13:/bin/bash
stu14:x:1014:1014::/home/stu14:/bin/bash
stu15:x:1015:1015::/home/stu15:/bin/bash
stu16:x:1016:1016::/home/stu16:/bin/bash
stu17:x:1017:1017::/home/stu17:/bin/bash
stu18:x:1018:1018::/home/stu18:/bin/bash
stu19:x:1019:1019::/home/stu19:/bin/bash
stu20:x:1020:1020::/home/stu20:/bin/bash
[root@localhost ~]# vi pricegame.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品实际价格范围为0-999,猜猜看是多少?"
while true
do
read -p "请输入你猜测的价格:" INT
let TIMES++
if [ $INT -eq $PRICE ]
then
echo "恭喜你猜对了,实际价格是$PRICE"
echo "你总共猜了$TIMES次"
exit 0
elif [ $INT -gt $PRICE ]
then
echo "太高了!"
else
echo "太低了!"
fi
done
[root@localhost ~]# chmod +x pricegame.sh
1.3 until循环语句
[root@localhost ~]# vi sum1to50.sh
#!/bin/bash
i=0
s=0
until [ $i -ge 50 ]
do
let "i=$i+1"
let "s=$s+$i"
done
echo "1加到50的和为:" $s
[root@localhost ~]# chmod +x sum1to50.sh
[root@localhost ~]# ./sum1to50.sh
1加到50的和为: 1275
二 Shell函数
2.1 Shell函数
[root@localhost ~]# vi sum.sh
#!/bin/bash
sum(){
read -p "请输入第一个数:" NUM1
read -p "请输入第二个数:" NUM2
echo "你输入的两个数为:" $NUM1和$NUM2
SUM=$((NUM1 + NUM2))
echo "两个数的和为: $SUM"
}
sum
[root@localhost ~]# ./sum.sh
请输入第一个数:10
请输入第二个数:20
你输入的两个数为: 10和20
两个数的和为: 30
[root@localhost ~]# vi function
servicectl_usage(){
echo "Usage:servicectl<service-name><start|stop|restart|reload|status>"
return 1
}
chk_centos_ver(){
grep "CentOS.*release 7." /etc/centos-release &>/dev/null && echo "7"
grep "CentOS.*release 6." /etc/centos-release &>/dev/null && echo "6"
grep "CentOS.*release 5." /etc/centos-release &>/dev/null && echo "5"
}
servicectl(){
[[ -z $1 || -z $2 ]] && servicectl_usage
[ $(chk_centos_ver)=="7" ] && systemctl $2 ${1}.service || service $1 $2
}
[root@localhost ~]# chmod +x function
[root@localhost ~]# source function
[root@localhost ~]# echo 'source /root/function' >> ~/.bashrc
[root@localhost ~]# servicectl vsftpd status
2.2 函数的作用范围
[root@localhost ~]# vi fun_scope.sh
myfun()
{
local i
i=8
echo $i
}
i=9
myfun
echo $i
[root@localhost ~]# chmod +x fun_scope.sh
[root@localhost ~]# ./fun_scope.sh
8
9
2.3 函数的参数
[root@localhost ~]# vi write_log.sh
#!/bin/bash
mydir="/data"
outfile="${mydir}/my.log"
[ -e "${mydir}" ] || mkdir -p ${mydir}
appendfile()
{
echo "$2" >> "$1"
}
appendfile ${outfile} "first line content"
appendfile ${outfile} "second line content"
[root@localhost ~]# chmod +x write_log.sh
[root@localhost ~]# ./write_log.sh
[root@localhost ~]# cat /data/my.log
first line content
second line content
2.4 递归函数
[root@localhost ~]# vi fun_recursion.sh
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 ~]# chmod +x fun_
fun_recursion.sh fun_scope.sh
[root@localhost ~]# chmod +x fun_recursion.sh
[root@localhost ~]# ./fun_recursion.sh
anaconda
anaconda.log
ifcfg.log
journal.log
ks-script-9EcVF8.log
packaging.log
program.log
storage.log
......
三 Shell数组
3.1 Shell数组
(1)获取数组长度
[root@localhost ~]# a=(1 2 3 4 5)
[root@localhost ~]# a=${#a[*]}
[root@localhost ~]# echo $a
5
(2)读取某下标赋值
[root@localhost ~]# a2=${a[2]} //第三个元素
[root@localhost ~]# echo $a2
3
(3)数组遍历
[root@localhost ~]# vi a.sh
#!/bin/bash
a=(1 2 3 4 5)
for v in ${a[*]}
do
echo $v
done
[root@localhost ~]# chmod +x a
anaconda-ks.cfg a.sh
[root@localhost ~]# chmod +x a.sh
[root@localhost ~]# ./a.sh
1
2
3
4
5
(4)数组切片
[root@localhost ~]# a=(1 2 3 4 5)
[root@localhost ~]# echo ${a[*]} //输出整个数组
1 2 3 4 5
[root@localhost ~]# echo ${a[*]:0:2} //${数组名[@或*]:起始位置:长度}
1 2
[root@localhost ~]# echo ${a[*]:2:3}
3 4 5
(5)数组切换
[root@localhost ~]# a=(1 2 3 4 5)
[root@localhost ~]# echo ${a[*]/4/7} //j将数组a里面的字符4替换成7
1 2 3 7 5
[root@localhost ~]# echo ${a[*]} //并不会替换数组原有内容
1 2 3 4 5
[root@localhost ~]# a=(${a[*]/4/7}) //实现永久替换
[root@localhost ~]# echo ${a[*]}
1 2 3 7 5
(6)数组删除
[root@localhost ~]# a=(1 2 3 4 5)
[root@localhost ~]# unset a //删除数组
[root@localhost ~]# echo ${a[*]}
[root@localhost ~]# a=(1 2 3 4 5)
[root@localhost ~]# unset a[2] //删除第三个元素
[root@localhost ~]# echo ${a[*]}
1 2 4 5
3.2 Shell脚本调试
在 Shell 脚本开发中,经常碰到一些规范方面的问题,例如忘了使用引号或在 if 语句末尾处忘记加 fi 结束。要注意把复杂的脚本简单化,要思路清晰,并且分段实现。当执行脚本时出现错误后,不要只看那些提示的错误行,而是要观察整个相关的代码段。
为避免编写的脚本出错,除了在编写脚本时注意书写规范,排除语法错误,更重要的是 利用调试脚本工具来调试脚本。echo 命令是最有用的调试脚本工具之一,一般在可能出现问题的脚本中加入 echo 命令,采用的是分段排查的方式。
■常用参数的具体含义为:
-n:不会执行该脚本,仅查询脚本语法是否有问题,如果没有语法问题就不显示任 何内容,如果有问题会提示报错。
-v:在执行脚本时,先将脚本的内容输出到屏幕上然后执行脚本,如果有错误,也 会给出错误提示。
-x:将执行的脚本内容输出到屏幕上,这个是对调试很有用的参数。
#!/bin/bash
set -x //开启调试模式
read -p "请输入您的分数(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] then
echo "$GRADE 分!优秀"
set +x //关闭调试模式
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] then
else fi
echo "$GRADE 分,合格"
echo "$GRADE 分?不合格"