本文共 8270 字,大约阅读时间需要 27 分钟。
脚本:一个可执行的文件,可以实现某种功能
明确任务需求---> 编写代码文件---> 测试并完善
案例1:书写脚本可以在命令行,输出“Hello World”
[root@server0 ~]# vim /root/hello.sh echo Hello World[root@server0 ~]# /root/hello.sh
-bash: /root/hello.sh: 权限不够 [root@server0 ~]# chmod +x /root/hello.sh [root@server0 ~]# ls -l /root/hello.sh -rwxr-xr-x. 1 root root 17 3月 7 09:26 /root/hello.sh[root@server0 ~]# /root/hello.sh
Hello World 规范Shell脚本的一般组成1)输出当前红帽系统的版本信息 2)输出当前使用的内核版本 3)输出当前系统的主机名 [root@server0 ~]# vim /root/hello.sh #!/bin/bash echo hello world cat /etc/redhat-release uname -r hostname ifconfig | head -2 [root@server0 ~]# chmod +x /root/hello.sh
[root@server0 ~]# /root/hello.sh
简单脚本技巧 重定向输出 >: 只收集前面命令的正确输出 2>: 只收集前面命令的错误输出 &> 使用变量:收集前面命令的正确与错误输出 [root@server0 ~]# echo 123 > /opt/1.txt [root@server0 ~]# cat /opt/1.txt[root@server0 ~]# cat /abc
[root@server0 ~]# cat /opt/1.txt /abc [root@server0 ~]# cat /opt/1.txt /abc > /mnt/a.txt [root@server0 ~]# cat /mnt/a.txt[root@server0 ~]# cat /opt/1.txt /abc 2> /mnt/a.txt
[root@server0 ~]# cat /mnt/a.txt[root@server0 ~]# cat /opt/1.txt /abc &> /mnt/a.txt
[root@server0 ~]# cat /mnt/a.txt
使用变量
/dev/null:黑洞设备,专用于收集不要的输出信息
案例2:书写创建用户脚本
[root@server0 ~]# vim /root/user.sh #!/bin/bash useradd nsd04 &> /dev/null echo 用户nsd04创建成功 echo 123 | passwd --stdin nsd04 &> /dev/null echo 用户nsd04密码设置成功[root@server0 ~]# chmod +x /root/user.sh
[root@server0 ~]# /root/user.sh为了提高脚本灵活度,适应多变的环境,使用变量
变量=容器 以不变的名称,存储可以变化的值 变量名前面加$ 代表使用变量储存的值 [root@server0 ~]# vim /root/user.sh #!/bin/bash abc=tc useradd $abc &> /dev/null echo 用户$abc创建成功 echo 123 | passwd --stdin $abc &> /dev/null echo 用户$abc密码设置成功[root@server0 ~]# harry natasha kenji
为了让脚本更加智能,所以产生交互
read 1.产生交互 2.记录用户在键盘上的输入 3.将记录的内容,赋值给一个变量储存 -p :'屏幕输出信息' 必须要加上单引号[root@server0 ~]# vim /root/user.sh
#!/bin/bash read -p '请输入您要创建的用户名:' abc read -p '请输入您要设置的密码:' nsd useradd $abc &> /dev/null echo 用户$abc创建成功 echo $nsd | passwd --stdin $abc &> /dev/null echo 用户$abc密码设置成功 [root@server0 ~]#单引号:取消所有特殊字符的意义
[root@server0 ~]# echo '*' * [root@server0 ~]# echo '* | ? [] {}' * | ? [] {} [root@server0 ~]# abc=2000 [root@server0 ~]# echo $abc 2000 [root@server0 ~]# echo '$abc' $abc [root@server0 ~]#反撇号 ` ` 或 $( ) :将命令的输出结果,直接参与另一条命令的运行
[root@server0 ~]# date
2019年 03月 07日 星期四 14:09:00 CST [root@server0 ~]# date +%F #只显示 年-月-日 [root@server0 ~]# mkdir /opt/mydir-`date +%F` [root@server0 ~]# ls /opt/[root@server0 ~]# mkdir /opt/nsd-$(date +%F)
[root@server0 ~]# ls /opt/[root@server0 ~]# mkdir /opt/$(hostname)-$(date +%F)
[root@server0 ~]# ls /opt/
• 以不变的名称存放的可能会变化的值
– 变量名=变量值 – 方便以固定名称重复使用某个值 – 提高对任务需求、运行环境变化的适应能力 – 等号两边不要有空格 – 变量名仅由字母/数字/下划线组成,区分大小写 – 变量名不能以数字开头,不要使用关键字和特殊字符 – 若指定的变量名已存在,相当于为此变量重新赋值查看/引用变量
• 基本格式 – 引用变量值:$变量名 – 查看变量值:echo $变量名、echo ${变量名} [root@server0 ~]# a=rhel [root@server0 ~]# echo $a rhel [root@server0 ~]# echo $a7[root@server0 ~]# echo ${a}7
rhel7 [root@server0 ~]#环境变量: 变量名大写,由系统定义并且赋值完成 USER=当前登陆的用户名
[root@server0 ~]# echo $USER
root [root@server0 ~]# su - student [student@server0 ~]$ echo $USER student [student@server0 ~]$ exit logout [root@server0 ~]#位置变量
• 在执行脚本时提供的命令行参数 – 表示为 $n,n为序号 – $1、$2、.. .. ${10}、${11}、.. .. [root@server0 ~]# vim /root/2.sh #!/bin/bash cat -n $1 | head -$2[root@server0 ~]# chmod +x /root/2.sh
[root@server0 ~]# /root/2.sh /etc/passwd 4[root@server0 ~]# vim /root/user.sh
#!/bin/bash #read -p '请输入您要创建的用户名:' abc #read -p '请输入您要设置的密码:' nsd useradd $1 &> /dev/null echo 用户$1创建成功 echo $2 | passwd --stdin $1 &> /dev/null echo 用户$1密码设置成功 [root@server0 ~]# /root/user.sh jack 123456 预定义变量$# 已加载的位置变量的个数 $* 所有位置变量的值
$? 程序退出后的状态值,0正常,非0异常
[root@server0 ~]# vim /root/3.sh #!/bin/bash echo $1 echo $2 echo $3 echo $# echo $* [root@server0 ~]# /root/3.sh [root@server0 ~]# /root/3.sh haha xixi hehe lele[root@server0 ~]# vim /root/4.sh
#!/bin/bash echo 您一共输入了$#个,分别为$* [root@server0 ~]# /root/4.sh haha xixi hehe lele hengheng$? 程序退出后的状态值,0表示正常,其他值异常
判断上一个命令是否成功运行 条件测试及选择测试操作
• 几种可用的测试方式 [ 测试表达式 ] #每一部分之间都要有空格常用的测试选项
• 检查文件状态 -e:文档存在为真 -d:文档存在且必须目录,才为真 -f:文档存在且必须文件,才为真 -r:文档存在且必须对其有读取权限,才为真 -w:文档存在且必须对其有写入权限,才为真 -x:文档存在且必须对其有执行权限,才为真 [root@server0 ~]# [ -e /etc ] [root@server0 ~]# echo $?[root@server0 ~]# [ -e /abc ]
[root@server0 ~]# echo $?[root@server0 ~]# [ -d /etc/passwd ]
[root@server0 ~]# echo $?[root@server0 ~]# [ -f /etc/passwd ]
[root@server0 ~]# echo $?• 比较整数大小
-gt:大于 -ge:大于等于 -eq:等于 -ne:不等于 -lt:小于 -le:小于等于• 字符串比对
== :相等一致为真 != : 不相等为真 [root@server0 ~]# [ haha == xixi ] [root@server0 ~]# echo $? 1 [root@server0 ~]# [ $USER == root ] [root@server0 ~]# echo $? 0 [root@server0 ~]# [ haha != xixi ] [root@server0 ~]# echo $? 0 [root@server0 ~]#if双分支处理
if [条件测试];then
命令序列xx else 命令序列yy fi[root@server0 ~]# vim /root/if01.sh
#!/bin/bash if [ $1 -eq 1 ];then echo hello else echo xixi fi [root@server0 ~]# chmod +x /root/if01.sh[root@server0 ~]# /root/if01.sh 1
[root@server0 ~]# /root/if01.sh 2 if多分支处理if [条件测试1];then
命令序列xx elif [条件测试2];then 命令序列yy elif 可以有很多个else
命令序列zz fi 案例:书写一个成绩的脚本用户输入成绩,进行判断
如果大于等于90分,则输出 优秀 如果大于等于80分,则输出 良好 如果大于等于70分,则输出 一般 如果大于等于60分,则输出 合格 以上条件均不满足,则输出 在牛的肖邦,也弹不出哥的悲伤 [root@server0 ~]# vim /root/if02.sh #!/bin/bash read -p '请输入您的成绩:' num if [ $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
for循环处理
• 遍历/列表式循环 – 根据变量的不同取值,重复执行xx处理for 变量名 in 值列表
do 命令序列 done for 献血车 in zhangsan lisi dc tom harry do 抽血 done案例:循环创建用户
[root@server0 ~]# vim /root/for01.sh #!/bin/bash for a in zhangsan lisi tom natasha harry kenji do useradd $a &> /dev/null echo $a创建成功 done[root@server0 ~]# chmod +x /root/for01.sh
[root@server0 ~]# /root/for01.sh循环的列表值,可以与重复执行的操作无关
[root@server0 ~]# vim /root/for01.sh
#!/bin/bash for a in {1..4} do echo I Love Dc done造数工具: {起始..结束}
{1..20}:制造连续范围内的数字,1至20[root@server0 ~]# echo {1..30}
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 [root@server0 ~]# touch /opt/stu{1..20}.txt [root@server0 ~]# ls /opt/
案例:用户输入IP地址,进行判断
本机是否可以与用户输入的IP,进行通信
如果可以通信,则输出 可以通信 如果不可以通信,则输出 不可以通信[root@server0 ~]# vim /root/ip.sh
#!/bin/bash read -p '请输入测试的IP地址:' ip ping -c 2 $ip &> /dev/null if [ $? -eq 0 ];then echo $ip可以通信 else echo $ip不可以通信 fi [root@server0 ~]#
案例4:编写一个判断脚本
在 server0 上创建 /root/foo.sh 脚本 1)当运行/root/foo.sh redhat,输出为fedora 2)当运行/root/foo.sh fedora,输出为redhat 3)当没有任何参数或者参数不是 redhat 或者 fedora时,其错误输出产生以下信息: /root/foo.sh redhat|fedora案例5:编写一个批量添加用户脚本
在 server0 上创建 /root/batchusers 脚本 1)此脚本要求提供用户名列表文件作为参数 2)如果没有提供参数,此脚本应该给出提示 Usage: /root/batchusers,退出并返回相应值 3)如果提供一个不存在的文件,此脚本应该给出提 示 Input file not found,退出并返回相应值 4)新用户的登录Shell为 /bin/false,无需设置密码 5)用户列表测试文件: http://classroom/pub/materials/userlist
案例4:编写一个判断脚本
在 server0 上创建 /root/foo.sh 脚本 1)当运行/root/foo.sh redhat,输出为fedora 2)当运行/root/foo.sh fedora,输出为redhat 3)当没有任何参数或者参数不是 redhat 或者 fedora时,其错误输出产生以下信息: /root/foo.sh redhat|fedora[root@server0 ~]# vim /root/foo.sh
#!/bin/bash if [ $# -eq 0 ];then #判断是否输入参数 echo '/root/foo.sh redhat|fedora' >&2 #将正确信息变成错误信息 exit 38 #脚本退出,返回的状态值 elif [ $1 == redhat ];then echo fedora elif [ $1 == fedora ];then echo redhat else echo '/root/foo.sh redhat|fedora' >&2 #将正确信息变成错误信息 exit 39 #脚本退出,返回的状态值 fi [root@server0 ~]#
案例5:编写一个批量添加用户脚本
在 server0 上创建 /root/batchusers 脚本 1)此脚本要求提供用户名列表文件作为参数 2)如果没有提供参数,此脚本应该给出提示 Usage: /root/batchusers,退出并返回相应值 3)如果提供一个不存在的文件,此脚本应该给出提 示 Input file not found,退出并返回相应值 4)新用户的登录Shell为 /bin/false,无需设置密码 5)用户列表测试文件: http://classroom/pub/materials/userlist[root@server0 ~]# vim /root/batchusers
#!/bin/bash if [ $# -eq 0 ];then #判断是否输入参数 echo 'Usage: /root/batchusers' >&2 exit 2 elif [ -f $1 ];then #判断文件是否存在 for i in $(cat $1) do useradd -s /bin/false $i &> /dev/null echo $i 创建成功 done else echo 'Input file not found' >&2 exit 3 fi[root@server0 ~]# vim /root/userlist
zhangsan lisi dc [root@server0 ~]# /root/batchusers /root/userlist
案例3:Shell脚本(利用位置变量,实现用户输入参数)
为系统 server0 书写脚本/root/user.sh 运行脚本,可以判断用户输入的用户是否存在 如果存在,输出用户基本信息(id 用户名) 如果用户,不存在则创建用户,并输出用户创建成功[root@server0 ~]# vim /root/user.sh
#!/bin/bash id $1 &> /dev/null if [ $? -eq 0 ];then echo $1用户已经存在 id $1 else useradd $1 echo $1用户创建成功 fi [root@server0 ~]# cat /root/user.sh #!/bin/bash useradd $1 &> /dev/null if [ $? -eq 0 ];then echo $1用户创建成功 else echo $1用户已经存在 id $1 fi转载地址:http://eeiqi.baihongyu.com/