Linux中Shell
Shell是什么
Shell是一个命令行解释器,为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,可以用Shell来启动、挂起、停止、编写一些程序。
Shell脚本的执行方式
脚本格式要求
- 脚本以 #!/bin/bash 开头
- 脚本需要有 执行权限
范例
#!/bin/bash
echo "hello world!"
执行方式
- 方式一
- 给 xx.sh 赋予 +x 的权限
- 执行脚本
- 方式二
- sh xx.sh
Shell变量
- 变量分为:系统变量和自定义变量。
- 系统变量:【$HOME]、$PWD 、$USER 等 : 区分大小写
- 显示当前 shell 中所有变量 : set
定义
- 定义变量:变量=值
- 撤销变量:unset 变量
- 申明静态变量:readonly 变量, 不能执行 unset
变量定义规则
- 变量由 字母、数字、和下划线组成,不能以 数字开头。
- 等号两侧不能有空格
- 变量名称一般大写
使用 ``
A=`ls -la` :把执行结果 返回给变量 A
====================
A=$(ls -la)
设置环境变量
- export 变量名=变量值:将shell变量输出为环境变量
- export 配置文件:让修改后的配置文件生效
- export $变量名:查询环境变量的值
位置参数变量
$n :$0 代表 命令本身;$1 -- $9 :第一个到第九个参数,10及以上的参数,用 ${10}
$* :代表命令行中的所有参数, 看成一个整体
$@ :代表命令行中的所有参数,会把每个参数区分开
$# :代表命令行中所有参数的个数
echo "$0 $1 $2"
echo "$*"
echo "$@"
echo "参数个数=$#"
================
./position.sh 30 60
30 60
30 60
参数个数=2
预定义变量
Shell中已经定义好的变量,可以直接使用
$$:当前进程的PID
$!:后台运行的最后一个进程的PID
$?:最后一次执行的命令的返回状态。如果为0,表示上一个命令正确执行。
Shell运算符
$((运算符)) || $[运算符]
expr m + n : 运算符之间 有空格
expr m - n
计算 (2+3)*4
#!/bin/bash
echo "hello"
RESULT1=$(((2+3)*4))
echo "result1=$RESULT1"
RESULT2=$[(2 + 3) * 4]
echo "result2=$RESULT2"
TEMP=`expr 2 + 3`
RESULT3=`expr $TEMP \* 4`
echo "result3=$RESULT3"
Shell判断语句
[ condition ] :condition前后有空格
- [ 1 ] :true
- [] : false
- [ condition ] && echo 123 || echo 234
常用判断条件
- 数字的比较
= | 字符串比较 |
---|---|
-lt | 小于 |
-le | 小于等于 |
-eq | 等于 |
-gt | 大于 |
-ge | 大于等于 |
-ne | 不等 |
- 按照文件权限判断
-r | 有读的权限 |
---|---|
-w | 有写的权限 |
-x | 有执行的权限 |
- 按照文件类型判断
-f | 文件存在并且是一个常规文件 |
---|---|
-e | 文件存在 |
-d | 文件存在且是一个目录 |
Shell流程控制
If 语句
if [ condition ]
then XXX
elif [ condition ]
then xxx
fi
示例
if [ "ok" = "ok" ]
then echo "ok==ok"
fi
if [ 23 -gt 22 ]
then echo "gt"
fi
if [ -e /root/shell/aaa.txt ]
then echo "exist"
fi
case 语句
case $变量名 in
"值1")
echo "aaa";;
"值2")
echo "bbb";;
*)
echo "ccc";;
esac
#!/bin/bash
case $1 in
"1")
echo "aaa";;
"2")
echo "bbb";;
*)
echo "ccc";;
esac
------------------
./xx.sh 1
for 语句
for 变量 in 值1 值2 值3 ....
do
xxxx
done
for ((初始值; 循环控制条件;变量变化))
do
xxxx
done
示例
for i in "$*"
do
echo "num is $i"
done
# 只会打印一次,所有参数当成一个
===================
for j in "$@"
do
echo "num is $J"
done
# 多个参数会打印多行
#!/bin/bash
SUM=0
for((i=1;i<=100;i++))
do
SUM=$[$SUM+$i]
done
echo "SUM=$SUM"
while
语句
while [ condition ]
do
xxxx
done
#!/bin/bash
SUM=0
i=0
while [ $i -le $1 ]
do
SUM=$[$SUM+$i]
i=$[$i+1]
done
echo "SUM=$SUM"
Shell输入输出
read (选项)(参数):从控制台读取数据
-p:指定读取值时的提示符
-t:指定读值的等待时间【单位:秒】,超时不等待
参数:指定读取值的变量名
#!/bin/bash
read -p "input a number:" NUM1
echo "num1=$NUM1"
read -t 5 -p "在5秒内,输入一个数num=" NUM2
echo "num=$NUM2"
Shell函数
系统函数
1)basename:返回完整路径最后 / 的部分,常用于获取文件名
basename [pathname] [suffix]
basename /home/aaa/test.txt => test.txt
basename /home/aaa/test.txt .txt => test
2)dirname:返回完整路径最后 / 的前面部分,常用于获取路径
dirname 文件绝对路径
diename /home/aaa/test.txt ==>/home/aaa
自定义函数
语法
[function] funcName[()]
{
action;
[return int;]
}
示例
function getSum() {
SUM=$[$n1 + $n2]
echo "sum=$SUM"
}
read -p "first num1=" n1
read -p "second num2=" n2
getSum $n1 $n2
案例
需求:
- 每天凌晨 2 点 0分,备份数据库 testdb 到 /data/backup/db
- 备份开始和结束给出提示信息
- 备份好的文件要求以 备份时间为文件名,并打包 .tar.gz 格式:2019-02-23-09-02-01.tar.gz
- 同时检查 是否有超过10天的备份文件,有就执行删除操作
# 数据库定时备份 脚本
BACKUP_PATH=/data/backup/db
DATETIME=$(date +%Y-%m-%d-%H-%M-%S)
# echo "date=$DATETIME"
echo "========备份开始========="
echo "========备份路径=$BACKUP_PATH/$DATETIME.tar.gz==========="
HOST=localhost
USER=root
PWD=root
DB=testdb
# 如果路径不存在就新建
[ ! -d "$BACKUP_PATH/$DATETIME" ] && mkdir -p $BACKUP_PATH/$DATETIME
# 执行备份命令
mysqldump -u$USER -p$PWD --host=$HOST $DB | gzip > $BACKUP_PATH/$DATETIME/$DATETIME.sql.gz
cd $BACKUP_PATH
tar -zcvf $DATETIME.tar.gz $DATETIME
# 删除临时文件
rm -rf $BACKUP_PATH/$DATETIME
# 找10天前文件,并删除
find $BACKUP_PATH -mtime +10 -name "*.tar.gz" -exec rm -rf {} \;
# 输出备份结束信息
echo "==========备份成功==========="
- crontab -e
- 0 2 * * * /xxx.sh