shell脚本基础
Bash Shell的使用方式
- 交互式
人工干预、智能化程度高
逐条解释执行、效率低 - 非交互式
需要提前设计智能化难度大
批量执行、效率高
方便后台运行
什么是Shell脚本
- 提前设计可执行语句,用来完成特定任务的文件
解释性程序
顺序、批量执行
规范的Shell脚本的一般组成
- #!环境申明
- #注释文本
- 可执行代码
案例
任务要求:依次输出以下系统信息
红帽系统版本、内核版本、当前的主机名
[root@server1 home]# vim /root/sysinfo.sh
#!/bin/bash
cat /etc/redhat-release
uname -r
hostname
[root@server1 home]# bash /root/sysinfo.sh
Red Hat Enterprise Linux release 8.0 (Ootpa)
4.18.0-80.el8.x86_64
server1.net0.example.com
简单的脚本技巧
- 使用 | 管道操作
将前一条命令的标准输出作为后一条命令的输入
cmd1 | cmd2
[root@server1 ~]# echo 'hello' | mail -s test1 student
- 免交互处理
脚本一般在后台执行,要尽量的减少人工交互的语句 - 脚本输出信息的处理
记录有用的信息(>>/var/log/foo.log)
屏蔽没用的信息(&>/dev/null)
自定义输出:echo ‘文本字符串’ - 重定向输出(标准输出1和标准错误2)
- 将信息保存到文件中
cmd >file cmd>>file
cmd 2>file cmd 2>>file
cmd &>file cmd 2>file 1>&2
变量的使用
[student@server1 ~]# echo $USER
student
[root@server1 ~]# echo $USER
root
- 定义变量的规则
若指定的变量名已经存在,相当于为变量重新赋值
等号两边不要有空格
变量名有字母数字下划线组成,区分大小写
变量名不能以数字开头,不要使用关键字和特殊字符
[root@server1 ~]# X=12
[root@server1 ~]# var=3
- 查看变量/引用变量
引用变量:$变量名
查看变量:echo $变量名、echo ${变量名}
[root@server1 ~]# echo $X
12
[root@server1 ~]# echo ${var}25
325
- 变量的分类
环境变量:变量名一般都大写,用来设置用户/系统环境
PWD、PATH、USER、LOGNAME、SHELL、HOME
位置变量:bash内置,存储执行脚本时提供的参数
$n,n为序号
预定义变量:bash内置,,可直接调用的特殊值,不能够修改
$#:已加载的位置变量的个数
$?:程序退出后的状态值
自定义变量:用户自主设置、修改及使用
条件测试和选择
shell测试的依据
- 命令行/程序的退出的状态值$?
值为0,表示执行成功
值为一:表示执行失败或者异常 - 在脚本中自定义退出的状态值
退出之前的最后一条命令的$?作为脚本退出的状态值
可以自己替换,添加exit 整数
测试操作
- 测试方法
正常命令行
test -选项 参数…
[测试表达式]
[root@server1 ~]# id lisi &>/dev/null
[root@server1 ~]# echo $?
1
[root@server1 ~]# [ 150 -gt 100 ]
[root@server1 ~]# echo $?
0
常见的测试选项
- 检查文件状态
-e、-d、-f - 比较整数大小
-gt、-ge、-le、-lt、-eq、-ne - 字符串比对
== 、!=
if选择结构
- 单分支结构
if 条件测试; then
命令序列xx
fi
- 双分支结构
if 条件测试; then
命令序列xx
else
命令序列yy
fi
- 多分支结构
if 条件测试; then
命令序列xx
elif
命令序列yy
else
命令序列zz
fi
列表式循环
- for循环结构
for 变量名 in 值列表
do
命令序列
done
利用名利代替取值
- 使用$(命令行)操作
先执行括号中的命令行,提取此命令行的标准输出
将标准输出结果替换成整个 $()表达式
可以作为参数嵌入到其他的命令行
[root@server1 ~]# cat /root/userlist
zs
ls
ww
zl
[root@server1 ~]# echo $(cat /root/userlist)
zs ls ww zl
案例:
本例要求在虚拟机 server0 上创建 /root/batchusers 脚本,任务目标如下:
此脚本要求提供用户名列表文件作为参数
如果没有提供参数,此脚本应该给出提示 Usage: /root/batchusers,退出并返回相应值
如果提供一个不存在的文件,此脚本应该给出提示 not found,退出并返回相应值
新用户的登录Shell为 /bin/false,无需设置密码
列表测试文件:http://classroom/pub/materials/userlist
#!/bin/bash
if [ $# -eq 0 ];then
echo 'Usage:/root/batchusers'
exit 1
fi
if [ ! -f $1 ];then
echo 'not found'
exit 2
fi
for i in $(cat $1)
do
useradd -s /bin/false $i
done
[root@server1 ~]# bash /root/batchusers.sh
Usage:/root/batchusers
[root@server1 ~]# echo $?
1
[root@server1 ~]# bash /root/batchusers.sh 1.txt
not found
[root@server1 ~]# echo $?
2
[root@server1 ~]# bash /root/batchusers.sh userlist
[root@server1 ~]# echo $?
0