Shell 基础
Shell脚本基础
什么是脚本:可以执行的一个文件,执行后可以实现某种功能
使用脚本输出hello World
# vim /root/hello.sh
# echo hello World!
# /root/hello.sh #运行时候发现没权限
# chmod +x /root/hello.sh #赋予所有用户执行权限
# /root/hello.sh
hello World!
规范:Shell脚本的一般组成
- #! 环境声明
- # 注释文本
- 可执行代码
重定向输出
> :只收集前面命令的正确输出
2> :只收集前面命令的错误输出
&> :收集前面命令的正确与错误输出
单引号和:都可以使特殊符号保持原型
``与 $()
```与 $() : #将命令的输出,将做参数直接参与下一个命令的运行`
这两个符号分别是 Bash Shell 中的命令替换和算术扩展运算符
$(command)
:将command
的输出作为一个字符串返回给 Bash 脚本。举个例子,echo $(ls)
会将当前目录下所有文件和文件夹的名称打印出来。$((expression))
:用来进行基本算术运算的符号。举个例子,echo $((1+2))
会输出3
。在$((expression))
中,可以使用加减乘除、取模、位运算等多种算术运算符。
需要注意的是,这两个符号在使用时需要注意语法规则,比如括号的匹配等问题。
--题:让系统每天备份一个文件夹,文件夹名称为nsd-时间(nsd-2023-3-14)
思路:定时任务,每天执行一个脚本,脚本里设置语句
- mkdir nsd-`date +%F`
- mkdir nsd-$(date +%F)
# crontab -e -u root
0 8 * * * mkdir /opt/nsp-$(date +%F)
:wq #保存退出
变量
会变化的量
为了适应多变的环境需求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J49LaAHP-1682328071218)(E:\ccstudy\markdown\img\脚本案例1.jpg)]
优化 - 传入变量
# a= 100
# echo a
a
# echo $a
100
#vim /root/user.sh
#! /bin/bash
# 新建用户 赋予密码
a=harry
useradd $a &> /dev/null #/dev/null相当于垃圾回收站,里面的文件会直接粉碎
echo 用户$a创建成功
echo 123 | passwd --stdin $a &> /dev/null
echo 用户$a密码设置成功
# chmod +x user.sh
# /root/user.sh
人机交互
在命令行向脚本中传递参数
read命令:1.产生交互
2.记录用户在键盘输入
3.将记录的信息赋值给一个变量存储
#vim /root/user.sh
#! /bin/bash
# 新建用户 赋予密码
read -p '请输入您要创建的用户名:' a # 只改这一个 -p添加提示信息
useradd $a &> /dev/null #/dev/null相当于垃圾回收站,里面的文件会直接粉碎
echo 用户$a创建成功
echo 123 | passwd --stdin $a &> /dev/null
echo 用户$a密码设置成功
:wq
[root@CC ~]# /root/user.sh
请输入您要创建的用户名:
jack
用户jack创建成功
用户jack密码设置成功
# # 让密码也使用变量
#vim /root/user.sh
#! /bin/bash
# 新建用户 赋予密码
read -p '请输入您要创建的用户名:' a # 只改这一个 -p添加提示信息
read -p '请输入您要创建的用户密码:' b
useradd $a &> /dev/null #/dev/null相当于垃圾回收站,里面的文件会直接粉碎
echo 用户$a创建成功
echo $b | passwd --stdin $a &> /dev/null
echo 用户$a密码设置成功
:wq
变量
变量由字母数字下划线组成,严格区分大小写
不能以数字开头,不能以关键字命名
等号两边不能有空格 Shell不能有
调用变量值 $变量名 , ${}
例: n a m e 拼接: name 拼接: name拼接:{name}7
变量种类:
环境变量 一般大写,用来设置用户/系统环境
USER=当前登录的身份
echo $USER
位置变量 bash内置,存储执行脚本时提供的命令行参数
表示为$n,n为序号
$1,$2, 3 , . . . , 3,..., 3,...,{10},${11}… 10以上要加{}
# # 使用位置变量非交互式添加账号
#vim /root/user.sh
#! /bin/bash
# 新建用户 赋予密码
#read -p '请输入您要创建的用户名:' a # 只改这一个 -p 添加提示信息
# read -p '请输入您要创建的用户密码:' b
useradd $1 &> /dev/null #/dev/null相当于垃圾回收 站,里面的文件会直接粉碎
echo 用户$1创建成功
echo $2 | passwd --stdin $1 &> /dev/null
echo 用户$1密码设置成功
:wq
[root@CC ~]# ./user.sh harry 123
用户harry创建成功
用户harry密码设置成功
预定义变量 bash内置,可直接调用的特殊值,不能直接修改
$# 已加载的位置变量的个数
# # 使用 $#
#vim /root/user.sh
#! /bin/bash
# 新建用户 赋予密码
#read -p '请输入您要创建的用户名:' a # 只改这一个 -p 添加提示信息
# read -p '请输入您要创建的用户密码:' b
useradd $1 &> /dev/null #/dev/null相当于垃圾回收 站,里面的文件会直接粉碎
echo 用户$1创建成功
echo $2 | passwd --stdin $1 &> /dev/null
echo 用户$1密码设置成功
echo 传进来的参数个数:$#
:wq
[root@CC ~]# ./user.sh harry 123 111
用户harry创建成功
用户harry密码设置成功
传进来的参数个数:3
# 会显示有三个参数,虽然脚本只是用了两个,但是他会计算命令行传进来多少个参数,而不是使用了多少个参数,主要用来做if判断,判断用户是否输入参数
$? 程序退出后的状态值,0正常,其他值异常
[root@CC ~]# useradd test1
[root@CC ~]# echo $?
0
[root@CC ~]# useradd test1
useradd: user 'test1' already exists
[root@CC ~]# echo $?
9
#可以用来判断上一条语句是否执行成功
自定义变量 用户自主设置、修改及使用
if 语句
测试表示式
[ 测试表达式 ]:里面的左右都要有空格
检查文件状态
-
**-e **: 文档存在才为真
-
-d : 文档存在,且必须为目录才为真
-
**-f **: 文档存在,且必须为文件才为真
[root@CC ~]# [ -e /etc ]
[root@CC ~]# echo $?
0
[root@CC ~]# [ -f /etc ]
[root@CC ~]# echo $?
1
[root@CC ~]# [ -f /etc/passwd ]
[root@CC ~]# echo $?
0
[root@CC ~]# [ -d /etc ]
[root@CC ~]# echo $?
0
[root@CC ~]# [ -d /etc/passwd ]
[root@CC ~]# echo $?
1
比较整数大小
- -gt :大于
- -ge :大于等于
- -e :等于
- -ne :不等于
- -lt : 小于
- -le : 小于等于
[root@CC ~]# [ 1 -gt 2 ]
[root@CC ~]# echo $?
1
字符串比较
- == :一致为真
- != :不一致为真
[root@CC ~]# [ $USER != root ]
[root@CC ~]# echo $?
1
[root@CC ~]# [ $USER == root ]
[root@CC ~]# echo $?
0
[root@CC ~]# [ xixi == haha ]
[root@CC ~]# echo $?
1
if 双分支处理
if [条件测试];then
命令序列xx
else
命令序列xy
fi
root@CC ~]# vim /root/test1.sh
#! /bin/bash
if [ $1 -eq 1 ];then
echo 相等
else
echo 不相等
fi
:wq
root@CC ~]# chmod +x /root/test1.sh
[root@CC ~]# ./test1.sh 1
相等
[root@CC ~]# ./test1.sh 1
不相等
# 对参数进行统计
#! /bin/bash
if [ $# -eq 0 ];then
echo 您没有输入参数
else
echo 您输入的参数个数为:$#
fi
# 写一个脚本:命令行输入一个用户,判断该用户是否存在
vim /root/ifuser.sh
#! /bin/bash
read -p '请输入您要测试的用户名:' a
id $a > /dev/null
if [ $? -eq 0 ];then
echo $a用户存在
else
echo "$a用户不存在"
fi
:wq
if 多条件分支
if [ 条件测试 ];then
命令序列xx
elif [ 条件测试2 ];then
命令序列yy
else
命令序列zz
fi
# 成绩查询脚本
#!/bin/bath
read -p '请输入你的成绩:' num
if [ $a -ge 90 ];then
echo 优秀
elif [ $a -ge 80 ];then
echo 良好
elif [ $a -ge 70 ];then
echo 一般
elif [ $a -ge 60 ];then
echo 合格
else
echo 不及格
fi
for 循环
for 变量名 in 值列表
do
命令序列
done
for a in zhangsan lisi wangwu
do
echo "我是$a"
done
# 循环的列表值,可以不参与循环执行的重复操作
for a in zhangsan lisi wangwu
do
echo "我爱吃饭" # 值列表完全不参与
done
造数工具
{x…y} 直接生成x到y
# 造数工具
for a in {1..10}
do
echo "我爱吃饭:$a" # 输出是我爱吃饭:1~10
done
>&2 错误信息
[root@CC ~]# echo "我爱吃饭"
我爱吃饭
[root@CC ~]# echo $?
0
[root@CC ~]# echo "我爱吃饭" >&2
我爱吃饭
[root@CC ~]# echo $?
1
if [ $1 -eq 0];then
echo "您未输入参数" >&2
exit 3 # 退出返回脚本状态值 相当于java传给前端的状态码
else
echo "$1"
fi
用户测试列表文件内容:
# 文件路径/root/userlisr
zhangsan
lisi
wangwu
zhaoliu
# vim /root/batchusers
#! /bin/bash
if [ $# -eq 0 ];then
echo "Usage:/root/batchusers" >&2
exit 3
elif [ -f $1 ];then
for a in $(cat $1) # $(cat /root/userlisr) # $(内容) 把内容的输出当成值参与运算
do
useradd -s /bin/false $a &> /dev/null
echo "$a创建成功"
done
else
echo Input file not fount >&2
fi
:wq
# /root/batchusers /root/userlisr