目录
一.概述
Shell是一个命令行解释器,它接收应用程序或者用户的命令,然后调用操作系统内核。
我们把很多命令放在一个文件,让Shell去执行,这个文件就叫脚本文件。
二.Linux提供的Shell解析器
# cat /etc/shells //查看解析器类型
# echo $SHELL //查看解析器,CentOS默认是/bin/bash
三.Shell入门
#!/bin/bash 开头 //指定解析器
1.执行一个简单的shell脚本
①建一个hello.sh文件(# touch hello.sh
)。
②打开hello.sh文件(# vim hello.sh
),并写入 #!/bin/bash
和 echo"hello,world"
。
③执行hello.sh文件
2.脚本常用的执行方法
第一种:采用 bash 或 sh 加 脚本的相对路径或绝对路径(不用赋予脚本 +x 权限)
sh+脚本的相对路径
# sh ./hello.sh
sh+脚本的绝对路径
# sh /root/shells/hello.sh
bash+脚本的相对路径
# bash ./hello.sh
bash+脚本的绝对路径
# bash /root/shells/hello.sh
第二种:输入脚本的绝对路径或相对路径执行脚本(必须赋予脚本 +x 权限)
# chmod +x shells/hello.sh //先赋予脚本可执行权限(x)
相对路径
# ./hello.sh
绝对路径
# /root/shells/hello.sh
四.变量
1.系统预定义变量
常用系统变量
$HOME、$PWD、$SHELL、$USER等。
查看系统变量
# echo $SHELL
显示所有变量
# set
显示系统全局变量
# env
2.自定义变量
基本语法
(1)定义变量:变量名=变量值。注意: =号前后不能有空格
(2)撤销变量:unset 变量名
(3)声明只读变量:# readonly 变量名=变量值。注意:不能 unset
(4)# export 变量名 //由局部变量变为全局变量
变量定义规则
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)在bash中,默认都是字符串类型,无所进行运算。
(3)变量的值如果包含空格,需要用双引号或单引号包含起来。
示例:
[root@liu100 ~]# my_test="hello world" //自定义变量
[root@liu100 ~]# echo $my_test //打印自定义变量
hello world
[root@liu100 ~]# readonly a=9 //自定义可读变量
[root@liu100 ~]# a=99 //修改可读变量(不可修改)
-bash: a: 只读变量
[root@liu100 ~]# unset my_test //撤销自定义变量
[root@liu100 ~]# echo $my_test //打印已经撤销的变量,已经没有了
[root@liu100 ~]# unset a //撤销自定义可读变量(不可撤销)
-bash: unset: a: 无法反设定: 只读 variable
3.特殊变量
$n //n的取值为 $0 表示脚本名称,$1-$9 代表一到九个参数,大于10,需要 ${10}这种形式。
hello.sh
脚本内容
hello1
和 hello2
是我们输入的两个参数值
$# //获取我们当前输入参数的个数
$* //获取命令行所有的参数,把所有参数看做一个整体
$@ //获取命令行所有的参数,把每个参数区分开来,相当于把参数放在一个集合中
$? //最后一次执行命令的返回状态。返回值是0代表上一个命令执行正确,否则上一个命令执行错误
五.运算符
$((运算式))或$[运算式] //对数字进行运算
六.条件判断
1.单条件判断
注意:条件表达式不是空即为 true
,否则为 false
,使用 $?
判断返回的是啥,0对应true,1对应false
# test 条件表达式 //条件判断
[ 条件表达式 ] //条件判断,前后都有空格
(1) 整数比较
注意字符串比较使用 =
判断相等,!=
判断不相等
常用判断条件 | 作用 |
---|---|
-eq | 等于(equal) |
-ne | 不等于(not equal) |
-lt | 小于(less than) |
-le | 小于等于(less equal) |
-gt | 大于(greater than) |
-ge | 大于等于(greater equal) |
(2) 按照文件权限比较
常用判断条件 | 作用 |
---|---|
-r | 读的权限 |
-w | 写的权限 |
-x | 执行的权限 |
(3) 按照文件类型比较
常用判断条件 | 作用 |
---|---|
-e | 文件存在(exittence) |
-f | 文件存在并且是一个文件(file) |
-d | 文件存在并且是一个目录(directory) |
[root@liu100 ~]# [ 1 = 2 ] //1=2吗 false
[root@liu100 ~]# echo $?
1
[root@liu100 ~]# [ 1 = 1 ] //1=1吗 true
[root@liu100 ~]# echo $?
0
[root@liu100 ~]# [ 1 -gt 2 ] //1>2吗 false
[root@liu100 ~]# echo $?
1
[root@liu100 ~]# [ -x hello.sh ] //hello.sh有执行权限吗 false
[root@liu100 ~]# echo $?
1
[root@liu100 ~]# [ -f /home/jjr ] // /home/jjr存在并且是文件吗 false
[root@liu100 ~]# echo $?
1
[root@liu100 ~]# [ -d /home/jjr ] // /home/jjr存在并且是目录吗 true
[root@liu100 ~]# echo $?
0
2.多条件判断
多条件判断
&&
表示前一条命令执行成功,才会执行,||
表示前一天命令执行失败才会执行和java里面的三元运算符类似。
七.流程控制(重点)
1.if判断
基本语法
(1) 单分支
if [ 条件判断式 ]; then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
(2) 多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项
(1) if 后面有空格, [ 条件判断式 ] 中括号里面前后也有空格。
(2) -a 相当于java里面的and,-o 相当于java里面的or。
多个条件判断式
脚本文件内容
执行脚本文件的结果
2.case语句
基本语法
case $变量值 in
"值1")
变量值等于值1,执行程序1
;;
"值2")
变量值等于值2,执行程序2
;;
...其他分支
*)
不匹配上面的所有值,执行这个程序
;;
esac
注意事项
(1) ;; 相当于java里面的 break
(2) *) 相当于java里面的 default
脚本文件内容
执行脚本文件的结果
3.for循环
基本语法
for ((初始值;循环控制条件;变量变化))
do
程序
done
或者
for 变量 in 值1 值2 值3...
do
程序
done
相当于java加强for循环
脚本内容 1-100 累加(普通for循环)
脚本执行结果
脚本内容 1-100 累加(加强for循环),执行结果和上图一样
4.while循环
基本语法
while [ 条件判断式 ]
do
程序
done
脚本内容 1-100 的累加
八.read读取控制台输入
基本语法
read [选项][参数]
选项:
-p:指定读取时的提示符
-t:指定读取值时等待的时间(秒) 如果不加-t表示一直等待
参数:
变量:指定读取值得变量名
脚本内容
执行脚本结果
九.函数
1.系统函数
- basename
基本语法
basename [string/pathname] [后缀名] //删除所有前缀,包括最后一个 / 字符(取路径里面的文件名称),如果加上后缀,他会把文件名里的后缀去掉
- dirname
基本语法
dirname 文件绝对路径 //从绝对路径中去除非目录的部分,然后返回目录的部分
- 自定义函数
基本语法
function(可省略) 函数名() //()也可省略
{
程序;
return int; //可省略,通过 $? 获取返回值
}
脚本内容
执行结果
十.正则表达式
常用特殊字符
^ //匹配一行的开头
例如:# cat /etc/passwd | grep ^a //匹配a开头的行
$ //匹配一行的结束
例如:# cat /etc/passwd | grep b$ //匹配b结束的行
. //匹配一个任意字符
例如:# cat /etc/passwd | grep c..d //匹配开头是c结尾是d的四个字符长度的所有行
* //表示匹配前一个字符0次或者多次
例如:# cat /etc/passwd | grep e*f //匹配e开头f结尾的不限长度的行
[] //匹配某个范围的字符
[6,8] //匹配6和8
[5-8] //匹配5到8
[0-9]* //匹配任意长度的数字字符串
[a-z] //匹配a-z之间的字符
[0-5,7-9] //匹配0-5或7-9之间的任意数字
例如:# cat /etc/passwd | grep g[a,b,c]h //匹配g开头h结尾之间必须是a或b或c的行
\ //表示转义 \* 代表 *符号
十一.文本处理工具
- cut
注意:默认分隔符是制表符
# cut [可选参数] 文件内容 //文件中负责剪切数据
# cut -f 1,2 -d " " //第一列和第二列按照 " "进行分割
参数 | 作用 |
---|---|
-f | 列号,提取第几列 |
-d | 分隔符,默认是制表符 |
-c | 按照字符进行分割,后面加n,表示取第几列 比如:-c 2 |
- awk
# awk [可选参数] '/pattern1/{action1} /pattern2/{action2}' 文件内容
参数 | 作用 |
---|---|
-F | 指定文件分隔符 |
-v | 赋值一个用户自定义变量 |
十二.实际案例
归档文件
需求:实现每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将日期附件在归档文件名上,放在 /home/jjr 目录下。
脚本内容:
#!/bin/bash
#判断输入的参数是一个
if [ $# -ne 1 ]
then
echo "仅能输入一个参数"
exit
fi
#获取参数中的目录
if [ -d $1 ]
then
echo
else
echo "目录不存在"
exit
fi
#获取你输入的路径的最后一个文件名或目录
file_name=$(basename $1)
#获取你输入路径的全路径
path_name=$(cd $(dirname $1);pwd)
#获取当前日期
DATE=$(date +%y%m%s)
#定义归档文件名称
file=ikun_${file_name}_$DATE.tar.gz
DIR=/home/jjr/$file
#归档
echo "开始归档"
tar -czf $DIR $path_name/$file_name
if [ $? -eq 0 ]
then
echo "归档成功"
else
echo "归档失败"
fi
exit
设置定时任务
# crontab -e //编辑定时任务,保存之后就会执行。 crontab -l 查看定时任务