Linux中Shell
Shell是什么
Shell是一个命令行解释器,为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,可以用Shell来启动、挂起、停止、编写一些程序。
Shell脚本的执行方式
脚本格式要求
- 脚本以 #!/bin/bash 开头
- 脚本需要有 执行权限
范例
1 2
| #!/bin/bash echo "hello world!"
|
执行方式
Shell变量
- 变量分为:系统变量和自定义变量。
- 系统变量:【\$HOME]、\$PWD 、\$USER 等 : 区分大小写
- 显示当前 shell 中所有变量 : set
定义
- 定义变量:变量=值
- 撤销变量:unset 变量
- 申明静态变量:readonly 变量, 不能执行 unset
变量定义规则
- 变量由 字母、数字、和下划线组成,不能以 数字开头。
- 等号两侧不能有空格
- 变量名称一般大写
==使用
==
1 2 3
| A=`ls -la` :把执行结果 返回给变量 A ==================== A=$(ls -la)
|
设置环境变量
- export 变量名=变量值:将shell变量输出为环境变量
- export 配置文件:让修改后的配置文件生效
- export $变量名:查询环境变量的值
位置参数变量
$n :\$0 代表 命令本身;\$1 – \$9 :第一个到第九个参数,10及以上的参数,用 \${10}
$* :代表命令行中的所有参数, 看成一个整体
$@ :代表命令行中的所有参数,会把每个参数区分开
$# :代表命令行中所有参数的个数
1 2 3 4 5 6 7 8 9
| 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
1 2 3 4 5 6 7 8 9
| #!/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 语句
1 2 3 4 5
| if [ condition ] then XXX elif [ condition ] then xxx fi
|
示例
1 2 3 4 5 6 7 8 9 10 11
| 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 语句
1 2 3 4 5 6 7 8
| case $变量名 in "值1") echo "aaa";; "值2") echo "bbb";; *) echo "ccc";; esac
|
1 2 3 4 5 6 7 8 9 10 11
| #!/bin/bash case $1 in "1") echo "aaa";; "2") echo "bbb";; *) echo "ccc";; esac ------------------ ./xx.sh 1
|
for 语句
1 2 3 4 5 6 7 8 9
| for 变量 in 值1 值2 值3 .... do xxxx done
for ((初始值; 循环控制条件;变量变化)) do xxxx done
|
示例
1 2 3 4 5 6 7 8 9 10 11
| for i in "$*" do echo "num is $i" done # 只会打印一次,所有参数当成一个 =================== for j in "$@" do echo "num is $J" done # 多个参数会打印多行
|
1 2 3 4 5 6 7
| #!/bin/bash SUM=0 for((i=1;i<=100;i++)) do SUM=$[$SUM+$i] done echo "SUM=$SUM"
|
while
语句
1 2 3 4
| while [ condition ] do xxxx done
|
1 2 3 4 5 6 7 8 9
| #!/bin/bash SUM=0 i=0 while [ $i -le $1 ] do SUM=$[$SUM+$i] i=$[$i+1] done echo "SUM=$SUM"
|
Shell输入输出
1 2 3 4 5
| read (选项)(参数):从控制台读取数据 -p:指定读取值时的提示符 -t:指定读值的等待时间【单位:秒】,超时不等待
参数:指定读取值的变量名
|
1 2 3 4 5 6 7
| #!/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]
1 2
| basename /home/aaa/test.txt => test.txt basename /home/aaa/test.txt .txt => test
|
2)dirname:返回完整路径最后 / 的前面部分,常用于获取路径
dirname 文件绝对路径
1
| diename /home/aaa/test.txt ==>/home/aaa
|
自定义函数
语法
1 2 3 4 5
| [function] funcName[()] { action; [return int;] }
|
示例
1 2 3 4 5 6 7 8
| 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天的备份文件,有就执行删除操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| # 数据库定时备份 脚本 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 "==========备份成功==========="
|