Shell Scripts是个自动管理系统软件的好工具,它可以简化我们日常工作管理,入侵检测呀,数据处理呀,而且很多服务都可以利用到它。它跨平台支持且学习历程短(不像程序语言那么难学哦)。
1.1 shell script其实就是一个文档(里面包含很多的命令,有简单的格式,一行一行的执行),可以直接用vim编辑(vim很适合写脚本哦)。
现在我们假设你写的这个程序文件名是/home/dmtsai/shell.sh 好了,那如何执行这个文件?
(1)直接指令下达:shell.sh 文件必须要具备可读与可执行(rx) 的权限,然后:
(2)以bash 程序来执行:透过「bash shellsh」或「sh shell.sh」来执行
(3)利用sh参数如-n及-x来检查shell脚本语法是否正确。
1.2 简单创建一个输出hello world脚本。(首先我们就要养成良好的编写脚本习惯,多写注释!)
最后直接执行这个文件就可以了
[user1@agent ~]$ mkdir bin;cd bin
[user1@agent bin]$ vim hello.sh
#!/bin/bash
#program :show "hello world" in your screen
#history
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "hello world!"
exit 0
[user1@agent bin]$ sh hello.sh
1.3 再来操作一个,在屏幕输出你的名字(程序取用你输入的变量)
注意理解脚本的意思呀:read -p就是让你输入,后面firstname就是获取变量,没有C语言复杂吧,最后echo -e输出,不过注意后面的形式,刚开始模仿就好了,慢慢就理解啦,不要一开始就放弃哦)
[user1@agent bin]$ vim showname.sh
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input your first name:" firstname
read -p "Please input your last name:" lastname
echo -e "\nYour full name is :${firstname}${lastname}"
[user1@agent bin]$ sh showname.sh
[user1@agent bin]$ sh showname.sh
Please input your first name:Jack
Please input your last name:chen
Your full name is :Jackchen
1.4 come on,再来一个,利用date实现对数据库文件的备份(这样就不用每次就修改文件,脚本啦)
1.5 实现简单的加减乘除 var=$((运算内容))
user1@agent bin]$ vim mutiply.sh
#!/bash/bin
#function:加减运算
#date 2020/03/30 author telephone
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input your first number:" firstnu
read -p "Please input your last number:" lastnu
total=$((${firstnu}*${lastnu}))
echo -e "the result of $firstnu * $lastnu = ${total}"
[user1@agent bin]$ sh mutiply.sh
Please input your first number:23
Please input your last number:23
the result of 23 * 23 = 529
计算有小数点的数据可借助bc这个指令,就是计算器哦,例如:
[user1@agent bin]$ echo "123.23*23.23" | bc
2862.63
然后我们计算pi的值(那个4*a(1)是bc主动提供的一个计算pi 的函数,至于scale 就是要bc计算几个小数点下位数的意思。当scale 的数值越大,代表 pi要被计算的越精确,当然用掉的时间就会越多)
1.6 source执行脚本和前面几种执行方式有差别。看下面的变量就知道了吧(用source可以将变量传送过来)
[user1@agent bin]$ sh showname.sh
Please input your first name:Jack
Please input your last name:chen
Your full name is :Jackchen
[user1@agent bin]$ echo $PATH
[user1@agent bin]$ source showname.sh
Please input your first name:JACK
Please input your last name:CHEN
Your full name is :JACKCHEN
[user1@agent bin]$ echo $PATH
/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/user1/bin
2.1 test指令测试:
判断是否存在这个目录,有就输出“exist”,没有就输出“not exist”
[user1@agent ~]$ test -e /user1 && echo "exist" || echo "not exist"
not exist
复习一下这个指令下达情况呀:
test具体的参数:(大家可以man一下看看就不用记那么多了,大概了解一些常用的就行)
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#1 让用户输入档名,判断是否输入
echo -e "please input a filename,I will check the filename's type and permission.\n"
read -p "input a filename :" filename
test -z ${filename} && echo "You must input a filename." && exit 0
#2.判断文件是否存在?若不存在则显示信息并结束脚本
test ! -e ${filename} && echo "The filename '${filename}' don't exist" && exit 0
#3.判断文件类型和属性
test -f ${filename} && filetype="regular file"
test -d ${filename} && filetype="directory"
test -r ${filename} && perm="readable"
test -w ${filename} && perm="${perm} writable"
test -x ${filename} && perm="excutable"
#4.print info
echo "the filename:${filename} is a ${filetype}"
echo "And the permission for you is : ${perm}"
2.2 还有个判断符号【】,看一下他们两效果是一样的。
[user1@agent bin]$ [ -z "${HOME}" ];echo $?
1
[user1@agent bin]$ test -z ${HOME};echo $?
1
2.3 shell script的默认变数
#用file查询这是一个可执行的脚本哦
[user1@agent bin]$ file /etc/init.d/network
/etc/init.d/network: Bourne-Again shell script, ASCII text executable
#这样可以重启网络
[user1@agent bin]$ /etc/init.d/network restart
#类似于下面两个都可以,我们到服务器会讲
[user1@agent bin]$ systemctl restart network
[user1@agent bin]$ service network restart
(1)格式如下:
(2)看个简单的实例(好好观察他们的格式呀,熟悉熟悉)
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "please input (Y/N):" yn
if [ "${yn}" = "y" ] || [ "${yn}" = "Y" ]; then
echo "ok,continue"
exit 0
fi
if [ "${yn}" = "n" ] || [ "${yn}" = "N" ]; then
echo "oh, interrupt"
exit 0
fi
echo "I don't know what your choice is" && exit 0
咱么让程序更简单明了一点:
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "please input (Y/N):" yn
if [ "${yn}" = "y" ] || [ "${yn}" = "Y" ]; then
echo "ok,continue"
exit 0
elif [ "${yn}" = "n" ] || [ "${yn}" = "N" ]; then
echo "oh, interrupt"
exit 0
else
echo "I don't knoe what your choice is" && exit 0
fi
(3)下面这个例子很有意思哦,grep过滤命令应该知道了把,我们编写netstat一个脚本去检测主机是否开启服务端口
虽然很长,但几乎都一样的。自己尝试下。
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#告知
echo "now,I will detect your linux server's services!"
echo -e "The www,ftp,ssh,and mail(smtp) will be detect!\n"
#start detecting! and echo some info
testfile=/dev/shm/netstat_checking.txt
netstat -tuln > ${testfile}
#先侦查,再判断
testing=$(grep ":80" ${testfile})
if [ "${testing}" != "" ];then
echo "www is running in your system."
else echo "www is not running"
fi
testing=$(grep ":22" ${testfile})
if [ "${testing}" != "" ];then
echo "ssh is running in your system."
else echo "ssh is not running"
fi
testing=$(grep ":21" ${testfile})
if [ "${testing}" != "" ];then
echo "ftp is running in your system."
else echo "ftp is not running"
fi
testing=$(grep ":25" ${testfile})
if [ "${testing}" != "" ];then
echo "mail is running in your system."
else echo "mail is not running"
fi
(1)while do done,until do done(不定循环)
当条件成立时,就进行循环,条件不成立就停止了。
看个例子,计算1+2+3+……+100的值,有助于我们了解。
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
s=0
i=0
while [ "${i}" != 100 ]
do
i=$(($i+1))
s=$(($s+$i))
done
echo "the result of '1+2+3+...+100' is => $s"
下面这个相反,当条件成立时就终止循环,否则持续。(这个我就不举例子了)
(2)for...do...done(固定循环)
看个例子(for循环和if判断一起用的例子->侦查192.168.1.1~192.168.1.100的主机 )
(3)for...do...done的数值处理(这个就很接近我们所学的C语言的for循环格式啦)
举个栗子:注意格式,我想大家都知道这个脚本的含义咯。
(4)再看一个非常有意思的脚本,这个搭配随机数和数组咯(利用这个告诉我们今天该吃什么)
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#输入选择
eat[1]="麦当劳汉堡"
eat[2]="肯德鸡炸鸡"
eat[3]="日式便当"
eat[4]="黄焖鸡"
eat[5]="大排面"
eat[6]="脆皮鸡饭"
eat[7]="蛋包饭"
eat[8]="吃泡面趴"
eat[9]="各自点外卖趴"
#需要输入几个有用的餐厅数
eatnum=9
#RANDOM随机生成0 - 32767之间的整数.
check=$(( ${RANDOM} *${eatnum} / 32767 +1 ))
echo "you may eat ${eat[${check}]}"
进阶版(输出三个吃的选择)
#!/bin/bash
#program :
#date:2020/03/30 Jack CentOS7.3 1297824292
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#输入选择
eat[1]="麦当劳汉堡"
eat[2]="肯德鸡炸鸡"
eat[3]="日式便当"
eat[4]="黄焖鸡"
eat[5]="大排面"
eat[6]="脆皮鸡饭"
eat[7]="蛋包饭"
eat[8]="吃泡面趴"
eat[9]="各自点外卖趴"
#需要输入几个有用的餐厅数
eatnum=9 #定义变量${eatnum}为9,即输入有几个可用的餐厅数
eated=0 #定义变量${eated}为0
while [ "${eated}" -lt 3 ]; do #${eated}小于3时即循环
check=$(( ${RANDOM}*${eatnum}/32767 + 1 ))
mycheck=0
if [ "${eated}" -ge 1 ]; then #判断${eated}是否大于等于1
for i in $(seq 1 ${eated}) #对于1-${eated}的连续的几个数
do
if [ ${eatedcon[$i]} == $check ]; then
mycheck=1
fi
done
fi
if [ ${mycheck} == 0 ]; then
echo "you may eat ${eat[${check}]}"
eated=$(( ${eated} + 1 ))
eatedcon[${eated}]=${check}
fi
done
(1)用bash加参数进行检测调试
#常用就是-n这个参数,检查语法有没有问题,没有输出就是OK的
[user1@agent bin]$ sh -n random_eat1.sh
#-x检测脚本执行过程
[user1@agent bin]$ sh -x random_eat1.sh
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/user1/bin
+ export PATH
+ eat[1]=麦当劳汉堡
+ eat[2]=肯德鸡炸鸡
+ eat[3]=日式便当
+ eat[4]=黄焖鸡
+ eat[5]=大排面
+ eat[6]=脆皮鸡饭
+ eat[7]=蛋包饭
+ eat[8]=吃泡面趴
+ eat[9]=各自点外卖趴
+ eatnum=9
+ check=8
+ echo 'you may eat 吃泡面趴'
you may eat 吃泡面趴
我们已经基本了解了shell基本的基本用法啦,实际工作中,现在网上有很多已经开发开放的脚本,我们就可以直接拿来修改来改成适合自己的主机的脚本咯(前提我们要看懂别人的脚本含义哦)。还有我们所学习sh检测方法至关重要哦,熟悉sh用法让你运用脚本更得心应手。遇到看不懂的脚本语句百度就能解决啦!记住学好学快脚本的方式就是多看,多模仿,并加以修改成自己的样式!
最后给大家奉上一个zabbix安装的脚本,有兴趣可以去观察模仿下哦!
如果各位学到一点知识的话可以点个赞哦,下面我会再写一些服务器安装脚本,LAMP部署脚本啥的哈