1.脚本的格式要求
- 脚本以#!/usr/bash开头,表示编写的脚本以bash这种终端解释器来解析。
- 脚本必须要有可执行权限
- 简单入门:
- 创建一个后缀名为.sh的文件。(当然后缀名并不是一定要是这个的,.sh是为了让用户清楚的知道这是一个脚本文件)
[xiaocer@localhost day1]$ vim helloworld.sh
- 在helloworld.sh文件中编辑如下内容:
#!/usr/bash echo "HelloWorld"
- 运行脚本文件
- 方式1,不推荐使用
[xiaocer@localhost day1]$ sh ./helloworld.sh
- 方式2:更改脚本文件的权限为可执行。然后运行该文件即可
[xiaocer@localhost day1]$ chmod 744 ./helloworld.sh
2.shell脚本的简单语法
1.系统变量与用户自定义变量的使用
- Linux shell中的变量分为系统变量和用户自定义变量。系统变量比如说PATH、HOME。$符号表示引用某个变量的值
echo "user=$HOME"
# 上述指令的输出结果为
/root
- 用户自定义变量的定义,定义一个变量a的规则有:
- 等号两边不能使用空格。
- 变量名由字母数字下划线组成,并且首字母只能是字母或者是下划线,不能是数字
- 变量名一般为大写
A=100
#自定义变量的使用
echo "A=$A"
#销毁某个自定义变量使用unset 变量名,表示撤销某个自定义变量
unset A
#a被销毁后就没有值了
echo "A=$a"
#shell中的静态变量(只读变量)的定义
readonly B=200
echo "B=$B"
#注意:静态变量是不能unset的,所以下面这句代码是错误的
#unset B
#将一个Linux终端中的命令的结果赋值给用户自定义变量可以这样:使用反引号将终端命令
#引起来。或者使用$符号。
C=`ls -la`
echo "C=$C"
D=$(ls -la);
echo "D=$D"
2.设置环境变量
- 在某个文件中将某个变量导出为环境变量:export 变量名=变量值
- 让修改后的配置信息生效:source 配置文件
- 查询环境变量的值:echo $变量名
- 示例
- 假设我们现在有一个配置文件ex.conf,然后我们在该文件中设置环境变量:
2.让该配置生效:export MYSQL_BIN_TEST=/root/practice
3.这样的话我们就可以在脚本文件中使用我们设置好的环境变量勒。在example.sh这个脚本文件中使用在其他文件中设置好的环境变量:source ./ex.conf
echo $MYSQL_BIN_TEST
3.位置参数变量的使用
- 当我们执行脚本时如果希望获取命令行的参数信息就可以使用位置参数变量。比如说
./example.sh 100 200
这是一个执行脚本的命令行,那么可以在脚本文件中获取100,200这两个参数信息。 - 基本语法:
$n
:n为数字。$0
代表命令本身,$1
~$9
代表第一到第九个参数。如果需要表示第九个以上的参数需要用大括号将数字括起来,比如说表示第十个参数:${10}
$*
:这个代表命令行中的所有参数,$*
将所有的参数看成一个整体。$@
:这个也代表命令行中所有的参数,不过$@
将命令行中的每个参数区分对待。对于$*
和$@
的区别在for循环里可以体现。$#
:代表命令行中的参数个数。
- 简单示例:
#shell中的位置参数变量的使用
echo "第一个参数:$1"
echo "第二个参数:$2"
echo $@
echo $*
echo "参数个数:$#"
# 输出结果为:
sh ex.conf 1 2 3 4 5
第一个参数:1
第二个参数:2
1 2 3 4 5
1 2 3 4 5
参数个数:5
4.预定义变量的使用
- shell预先定义好的变量,可以在shell脚本中直接使用
#shell中的预定义变量的使用
echo "当前进程id为:$$"
#输出结果
sh ex.conf
当前进程id为:51816
5.shell中运算符的使用
#shell中运算符的运用
#1.$((运算式))
echo $((100 + 200))
#2.expr 运算式,注意如果表示乘号需要用转义符\,也就是\*表示乘号。
#注意运算符与操作数之间需要空格,否则会报错。
expr 100 + 200
expr 100 \* 200
#输出结果为
sh ex.conf
300
300
20000
6.shell中的判断语句
1.基本语法:
- [ condition ],注意condition前后有空格
2.常用的判断条件:
- 两个整数的比较:
- =:字符串比较
- -lt:小于
- -le:小于或者等于
- -eq:等于
- -gt:大于
- -ge:大于或者等于
- -ne:不等于
- 按照文件权限进行判断
- -r:有读的权限
- -w:有写的权限
- -x:有执行的权限
- 按照文件类型进行判断
- -f:文件存在并且是一个常规的文件
- -e:文件存在
- -d:文件存在并且是一个目录文件。
3.示例
#shell中的判断语句
#案例1:判断“OK”是否等于“OK”
if [ "OKa" = "OK" ]
then
echo "equals"
fi
#2.案例二:判断/root/practice下是否存在example.sh文件
if [ -e /root/practice/example.sh ]
then echo "exits"
fi
7.流程控制
1.if语句
#shell中的if语句
if [ $1 -ge 60 ] #>= 60
then
echo "及格"
elif [ $1 -lt 60 ] # <60
then
echo "不及格"
fi
# 输出结果:
sh ex.conf 60
及格
2.case语句
#shell中的case语句
case $1 in
"1")
echo "周一"
;;
"2")
echo "周二"
;;
"3")
echo "other"
;;
esac
# 输出结果为
sh ex.conf 3
other
3.for循环
#shell中的for循环
#for循环语法一:
#案例一:打印出命令行下给出的所有参数,注意$*与$@区别
for i in "$*"
do
echo "the num is $i"
done
for j in "$@"
do
echo "the num is $j"
done
4.while循环
#案例:命令行中给定n的值,然后统计1+2+。。。+n的值
SUM1=0
i=0
while [ $i -le $1 ] # <= $1
do
SUM1=$[$SUM1+$i]
i=$[$i+1]
done
echo "SUM1=$SUM1"
8.read读取控制台输入
- 基本语法:
read 选项 参数
。常用的选项有:- -t:指定读取值时的等待时间,如果没有在指定的时间内输入就不等待了。
- -p:指定读取值时的提示符。p表示prompt,有提示的意思。
- 参数:参数就是指定读取值时的变量名
#shell中的read函数读取控制台的输入
#案例:读取控制台输入一个num1值,读取控制台输入一个num2值,在10秒内输入
read -p "请输入一个数:" NUM1
echo "num1=$NUM1"
read -t 10 -p "请输入一个数:" NUM2
echo "num2=$NUM2"
9.函数
1.系统函数
- 这里介绍常用的两个系统函数:
- basename: 返回完整路径/最后的部分,常用于获取文件名。语法为
basename string [suffix]
:string表示一个完整路径,suffix为后缀,如果suffix指定的话,basename会将string中的suffix去掉。 - dirname:返回完整路径最后/前面的部分,常用于返回路径部分。
dirname 文件绝对路径
。表示去除包含绝对路径的文件名部分(非目录部分),返回目录部分。
- basename: 返回完整路径/最后的部分,常用于获取文件名。语法为
- 示例:
- 在sysFunc.sh脚本文件中编辑如下内容:
basename /root/practice/ex.sh basename /root/practice/ex.sh .sh dirname /root/practice/ex.sh
- 运行结果如下:
sh example.sh ex.sh ex /root/practice
2.用户自定义函数
- 语法格式为:
function funcName ()
{
action;
[return int];
}
- 示例:
function add() {
sum=$[$a+$b]
echo "sum=$sum"
}
read -p "请输入第一个操作数:" a
read -p "请输入第二个操作数" b
add $a $b
10.综合举例如下:
- 编写一个脚本文件实现简单的加减乘除运算。
- 方法一:
#!/bin/bash ARGUNUM=$# #$#表示传入脚本参数的个数 if [ $ARGUNUM -gt 0 ] then NUM1=$1 NUM2=$2 NUM3=$3 case $2 in "+") echo $[$1+$3] ;; "-") echo $[$1-$3] ;; #这里我们以.表示乘号 ".") echo $[$1*$3] ;; "/") echo $[$1/$3] ;; esac fi #注意:判断语句中的表达式前后需要有空格 if [ $ARGUNUM -eq 0 ] then echo "failed,no arguments" fi
- 方法二:
read -p "输入三个数" NUM1 NUM2 NUM3 echo "$NUM1 $NUM2 $NUM3" case $NUM2 in "+") echo $[$NUM1+$NUM3] ;; "-") echo $[$NUM1-$NUM3] ;; ".") echo $[$NUM1*$NUM3] ;; "/") echo $[$NUM1/$NUM3] ;; esac
- 完成数据库的定时备份
#!/bin/bash
#完成数据库的定时备份。
#备份的路径
BACKUP=/root/practice/data/backup/db
#当前的时间作为文件名
DATETIME=$(date +%Y_%m_%d_%H%M%S)
#可以输出变量调试
#echo ${DATETIME}
echo "=======开始备份========"
echo "=======备份的路径是 $BACKUP/$DATETIME.tar.gz"
#主机
HOST=localhost
#用户名
DB_USER=root
#密码
DB_PWD=root
#备份数据库名
DATABASE=dataset_one
#创建备份的路径
#如果备份的路径文件夹存在,就使用,否则就创建
[ ! -d "$BACKUP/$DATETIME" ] && mkdir -p "$BACKUP/$DATETIME"
#执行mysql的备份数据库的指令
mysqldump -u${DB_USER} -p${DB_PWD} --host=$HOST $DATABASE | gzip > $BACKUP/$DATETIME/$DATETIME.sql.gz
#打包备份文件
cd $BACKUP
tar -zcvf $DATETIME.tar.gz $DATETIME
#删除临时目录
rm -rf $BACKUP/$DATETIME
#删除10天前的备份文件
find $BACKUP -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
echo "=====备份文件成功==========="
然后根据需求将这个脚本输入到任务调度文件中。
11.问题
- 问题描述:有的时候使用
sh xxx.sh
命令执行shell脚本报错Syntax error: "(" unexpected
- 问题解决:使用
bash xxx.sh
命令