##################################################################################################shell脚本: 脚本:可以执行的文件,运行之后实现某种功能(命令的堆积,交互式)规范shell脚本的一般组成:#! 环境声明# 注释文本可执行代码###############################################################################################一。书写第一个脚本程序#vim /root/1.sh#! /bin/bashecho "hello world" //输出hello worldhostname //输出主机名ifconfig | head -2 //输出网卡信息前两行cat /etc/redhat-release //输出系统版本信息#chmod +x /root/1.sh //赋予文件执行权限#/root/1.sh //执行脚本程序hello wordserver0.example.cometh0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.25.0.11 netmask 255.255.255.0 broadcast 172.25.0.255Red Hat Enterprise Linux Server release 7.0 (Maipo) //输出结果##################################################################################################二。书写为server0自动搭建yum的脚本#vim /root/yum.sh //创建脚本程序文件#! /bin/bashecho '[rhel] //yum仓库信息name=rhel //yum仓库名称baseurl=http://172.25.254.254/content/rhel7.0/x86_64/dvd/ //网络yum源地址enable=1 //开机自动加载gpgcheck=0' > /etc/yum.repos.d/rhel.repo //不进行签名认证,将这些内容重定向输出到文件/etc/yum.repos.d/rhel.repo#yum clean all //清空缓存#yum repolist //查看yum软件包信息#chmod +x /root/yum.sh //赋予执行权限#/root/yum.sh //执行脚本程序已加载插件:langpacks正在清理软件源: rhelCleaning up everything已加载插件:langpacksrhel | 4.1 kB 00:00 (1/2): rhel/group_gz | 134 kB 00:00 (2/2): rhel/primary_db | 3.4 MB 00:00 源标识 源名称 状态rhel rhel 4,305repolist: 4,305 //运行成功###############################################################################################################管道传递:管道操作:将上一条命令的标准输出交由下一条命令进行处理。免交互及输出处理:免交互处理: 脚本一般在后台进行,要减少人工交互的语句脚本输出信息处理:记录有价值的信息(>> /var/log/foo.log)屏蔽无价值的,干扰的信息(&> /dev/null)用户自定义输出:echo ‘文本字符串’重定向输出:标准输出:命令执行正常是显示结果标准错误:命令执行出错或异常时显示结果将屏幕信息保存到文件: > 将正确输出收集到文件当中 2> 将错误输出收集到文件当中 &> 收集前面命令的正确和错误输出 >&2 将命令的正确输出改为错误输出# echo 123 > /opt/a.txt# cat /opt/a.txt /etc123 //正确输出cat: /etc: 是一个目录 //错误输出# cat /opt/a.txt /etc > /opt/b.txt //只收集正确输出cat: /etc: 是一个目录# cat /opt/a.txt /etc 2> /opt/b.txt //只收集错误输出123# cat /opt/a.txt /etc &> /opt/b.txt //正确与错误输出全都收集#################################################################################################################三。书写创建用户并设置密码的脚本:# vim /root/user.sh#!/bin/bashuseradd test06 &> /dev/nullecho test06创建成功echo 123 | passwd --stdin test06 &> /dev/nullecho test06密码设置成功# chmod +x /root/user.sh# /root/user.sh #################################################################################################################变量:为了增加脚本适应环境的能力,增加脚本的灵活度,方便。变量:相当于容器,以不变的名称,储存变化的值。 变量名=变化的值 使用变量: $变量名 为了降低脚本使用难度,可以产生交互 read :可以产生交互,将键盘输入的内容赋值给变量#vim /root/user.shread -p "请输入您要创建的用户:" user //user为用户名变量read -p "请输入您要设置的密码:" pass //pass为用户密码变量useradd $user &> /dev/null //正确与错误信息全都收集在/dev/nullecho $user 创建成功echo $pass | passwd --stdin $user &> /dev/nullecho $user 密码设置成功#/root/user.sh请输入您要创建的用户:lala请输入您要设置的密码:12lala 创建成功lala 密码设置成功#######################################################################什么是变量 以不变的名称存放的可能会变化的值�C 变量名=变量值�C 方便以固定名称重复使用某个值�C 提高对任务需求、运行环境变化的适应能力 设置变量时的注意事项�C 若指定的变量名已存在,相当于为此变量重新赋值�C 等号两边不要有空格�C 变量名由字母/数字/下划线组成,区分大小写�C 变量名不能以数字开头,不要使用关键字和特殊字符 基本格式�C 引用变量值:$变量名�C 查看变量值:echo $变量名、echo ${变量名}变量的种类位置变量 在执行脚本时提供的命令行参数(非交互式传值)[root@server0 ~]# vim /root/2.sh#!/bin/bashecho $1echo $2echo $3echo ${10}echo ${11}# /root/2.sh haha benniu xixi hehe lele dc tc dz tz 100 200[root@server0 ~]# vim /root/3.sh #!/bin/bash cat -n $1 | head -$2 [root@server0 ~]# /root/3.sh /etc/passwd 2[root@server0 ~]# /root/3.sh /etc/passwd 3预定义变量 用来保存脚本程序的执行信息 �C 直接使用这些变量 �C 不能直接为这些变量赋值 $# 已加载的位置变量的个数 $* 所有位置变量的值 $? 程序退出后的状态值,0表示正常,其他值异常[root@server0 ~]# vim /root/2.sh #!/bin/bashecho $1echo $2echo $3echo ${10}echo ${11}echo $#echo $*[root@server0 ~]# /root/2.sh 1 2 3 4 5 6 7 8 9 10 11########################################################运算 [root@server0 ~]# expr 10 / 3[root@server0 ~]# expr 10 \* 3[root@server0 ~]# expr 1 + 2[root@server0 ~]# expr 3 - 1[root@server0 ~]# expr 10 % 3 #取余数 运算 $() :将命令的输出结果,作为参数[root@server0 opt]# date[root@server0 opt]# date +%F[root@server0 opt]# cd /opt[root@server0 opt]# mkdir $(date +%F)[root@server0 opt]# ls[root@server0 opt]# mkdir mydir-$(date +%F)[root@server0 opt]# ls[root@server0 opt]# mkdir MariaDB-$(date +%F)[root@server0 opt]# ls[root@server0 opt]# mkdir $(hostname)-$(date +%F)#######################################################常用的测试选项 检查文件状态 -e:文档存在为真 -d:文档存在且为目录为真 -f:文档存在且为文件为真 -r:文档存在且有读取权限为真 -w:文档存在且有写入权限为真 -x:文档存在且有执行权限为真 比较整数大小(带e都有等于二字,g代表大于,l代表小于) -gt:大于 -ge:大于等于 -eq:等于 -ne:不等于 -lt:小于 -le:小于等于 字符串比对 == :相等 !=:不相等########################################################if [ 条件测试 ] ; then 命令序列xxelse 命令序列yyfi[root@server0 /]# vim /root/5.sh#!/bin/bashif [ $1 -eq $2 ];then echo helloelse echo hifi[root@server0 /]# /root/5.sh 1 1 [root@server0 /]# /root/5.sh 1 2########################################################################################################### 请书写一个脚本: 用户输入一个IP地址(read),判断是否可以与该IP地址通信, 能通则输出 "IP ok" 否则 输出 "IP no"[root@server0 /]# vim /root/6.sh #!/bin/bash read -p '请输入一个IP地址:' ip ping -c 2 $ip &> /dev/null if [ $? -eq 0 ];then echo ${ip} ok else echo ${ip} no fi [root@server0 /]# /root/6.sh##########################################################################################if [条件测试1] ; then 命令序列xxelif [条件测试2] ; then 命令序列yyelse 命令序列zzfi 成绩 大于等于90 优秀 大于等于80 良好 大于等于70 及格 大于等于60 仍需努力 60以下 在牛的肖邦,也弹不出哥忧伤[root@server0 ~]# vim /root/8.sh#!/bin/bashread -p '请输入您的成绩:' numif [ $num -gt 100 ];then echo 成绩有误 elif [ $num -lt 0 ];then echo 成绩有误 elif [ $num -ge 90 ];then echo 优秀 elif [ $num -ge 80 ];then echo 良好 elif [ $num -ge 70 ];then echo 及格 elif [ $num -ge 60 ];then echo 仍需努力 else echo 在牛的肖邦,也弹不出哥忧伤fi############################################################################################################3在 server0 上创建 /root/foo.sh 脚本1)当运行/root/foo.sh redhat,输出为fedora2)当运行/root/foo.sh fedora,输出为redhat3)当没有任何参数或者参数不是 redhat 或者fedora时,其错误输出产生以下信息: /root/foo.sh redhat|fedora ' ':把所有的特殊字符,当作普通文本字符输出[root@server0 ~]# vim /root/foo.sh#!/bin/bashif [ $1 == redhat ];then echo fedoraelif [ $1 == fedora ];then echo redhatelse echo '/root/foo.sh redhat|fedora'fi[root@server0 ~]# /root/foo.sh redhat[root@server0 ~]# /root/foo.sh fedora[root@server0 ~]# /root/foo.sh haha存在的问题:当用户不输入任何参数时,表达式不成立;因为$1没有,所以表达式if [ $1 == redhat ];then,就相当于if [ == redhat ];then,相当于redhet在和一个不存在变量在比较;所以表达式不成立。#!/bin/bashif [ $# -eq 0 ];then echo '/root/foo.sh redhat|fedora' elif [ $1 == redhat ];then echo fedora elif [ $1 == fedora ];then echo redhatelse echo '/root/foo.sh redhat|fedora'fi存在问题:题中表示其错误输出表示为:/root/foo.sh redhat|fedora。但是,在我们运行此脚本,root/foo.sh redhat|fedora为正确输出,所以我们要将root/foo.sh redhat|fedora变为错误输出。 >&2 #将正确输出变成错误 " ":可以将 “没有” 变成 “ 空值”#!/bin/bashif [ "$1" == redhat ];then echo fedora elif [ "$1" == fedora ];then echo redhatelse echo '/root/foo.sh redhat|fedora' >&2 #将正确输出变成错误 exit 2 #脚本退出返回值fi解释:当用户不输入任何参数时,表达式[ "$1" == redhat ],相当于[ " " == redhat ]。表示一个空值,所以不相等,所以输出/root/foo.sh redhat|fedora################################################################################################################for循环结构 循环结构:将反复执行的语句,循环去执行 for 变量名 in 值列表 do 命令序列 done[root@server0 /]# vim /root/for.sh #!/bin/bash for a in 1 2 3 4 5 do useradd nsd$a echo nsd$a创建成功 done[root@server0 /]# vim /root/for02.sh #!/bin/bash for a in 1 2 3 4 5 do echo hello done##################################################################################################################案例5:编写一个批量添加用户脚本 在 server0 上创建 /root/batchusers 脚本 1)此脚本要求提供用户名列表文件作为参数 2)如果没有提供参数,此脚本应该给出提示 Usage: /root/batchusers,退出并返回相应值 3)如果提供一个不存在的文件,此脚本应该给出提 示 Input file not found,退出并返回相应值 4)新用户的登录Shell为 /bin/false,无需设置密码 5)用户列表测试文件: http://classroom/pub/materials/userlist# wget http://classroom/pub/materials/userlist [root@server0 /]# vim /root/batchusers#!/bin/bashif [ $# -eq 0 ];then //$#位置变量的数量,当不提供参数时,$#为0,表达式成立 echo 'Usage: /root/batchusers' >&2 //输出Usage: /root/batchusers >&2 变为错误输出 exit 1 //返回值为1,提示输入参数有误elif [ ! -f $1 ];then echo 'Input file not found' >&2 exit 2fifor a in $(cat $1)do useradd -s /bin/false $a echo $a创建成功done###################################################!/bin/bashif [ $# -eq 0 ];then echo 'Usage: /root/batchusers' >&2 exit 1elif [ -e $1 ];then for a in $(cat $1) do useradd -s /bin/false $a echo $a创建成功 done else echo 'Input file not found' >&2 exit 2fi###################################################