Linux03-Shell编程
1.开发中Shell的作用
- 编写数据库备份脚本。
- 编写大数据集群管理的脚本。
2.Shell简单Hello World
- Hello World程序。
#!/bin/bash # shell文件的开头,shell有多个版本,#!/bin/bash说明使用/bin/bash执行
echo 'hello word'
- Shell的执行。
- ./helloword.sh,直接执行需要有x执行的权限。
- sh hellowrd.sh,不需要x执行权限,也可以执行,但是不推荐。
3.Shell变量
- Shell变量分为系统变量和用户自定义变量。
- 系统变量。$HOME、$PATH、$USER、$SHELL。
- 用户自定义变量。
#!/bin/bash
# 系统变量,需要使用" "输出;'$PATH'不会解析,会直接输出 $PATH
echo "path=$PATH"
# 用户自定义变量
# 变量为由字母、数字、下划线组成,不能为数字开头。
# 等号两边不能有空格。A=10
# 变量一般为大写
A=$PATH
B=10
echo "A=$A"
echo "B=$B"
# 撤销定义
unset A
echo "A=$A"
# 静态变量,静态变量不能使用unset撤销定义
readonly C=10
echo "C=$C
- Shell中将命令返回的结果赋值给变量。
# 将返回结果赋值给变量的两种方式
D=`ls -a /`
E=$(ls -a /)
4.Shell配置环境变量
- 环境变量保存在/etc/profile中。
- 在/etc/profile底部追加命令,创建Java环境变量。
# 创建环境变量
JAVA=/opt/java
# 将环境变量导出
export JAVA
- source /etc/profile,刷新/etc/profile文件。刷新之后,就可以使用echo $JAVA查看/etc/profile中的$JAVA环境变量了。
5.Shell获取输入参数
- $n,通过参数的位置获取参数。$0,获取第一个参数;$1,获取第二个参数;获取第十一个参数 ${10},两位数需要加 ${10}。
- $*,获取所有参数,将参数当做一个整体。
- $@ 获取所有参数,将参数区别对待。
- $#,获取参数的个数。
- 通过./a01.sh a b,执行如下脚本。
#!/bin/bash
# 通过参数的位置获取参数
echo "$0 $1 $2" # ./a01.sh a b
# 获取所有参数
echo "$*" # a b
# 获取所有的参数
echo "$@" # a b
# 获取所有的参数
echo "$#" # 2
6.Shell预定义变量
- $$,获取执行当前任务的进程号。
- $!,获取后台运行的最后一个进程的进程号。
- $?,获取后台运行的最后一个进程的执行结果,0表示执行成功,非0表示上一个命令不正确。
- Shell实例脚本。
#!/bin/bash
echo "当前进程号=$$"
# & 后台运行
./a01.sh &
echo "最后一个进程号=$!"
echo "最后一个进程执行的结果=$?"
# 当前进程号=3925
# 最后一个进程号=3926
# 最后一个进程执行的结果=0
7.Shell基本运算
- Shell基本运算。
# + - \* / %,对应加;减;乘;除;取余。
- Shell运算的三种写法。
$((2+3))
$[2+3]
expr 2 + 3 # expr 运行符之间要有空格
- Shell实例脚本。
#!/bin/bash
A=$((2+3))
echo "A=$A"
B=$[2+4]
echo "B=$B"
C=`expr 2 + 5`
echo "C=$C"
D=$(expr 2 + 6)
echo "D=$D"
E=`expr 2 \* 3`
echo "E=$E"
# 输出
# A=5
# B=6
# C=7
# D=8
# E=6
8.Shell添加判断
- 基本判断。
= 字符串比较
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
- 文件权限判断。
-r 文件是否有读权限
-w 文件是否有写权限
-x 文件是否有执行权限
- 文件类型判断。
-f 文件存在并且是一个常规文件
-e 文件是否存在
-d 文件夹存在并且是一个目录
- Shell实例脚本。
#!/bin/bash
# 判断字符串是否相当,[]和表达式之间需要有空格。
if [ "hello" = "hello" ]
then
echo "=="
fi
# 小于
if [ 1 -lt 10 ]
then
echo "1 < 10"
fi
# a01.sh是否存在
if [ -e a01.sh ]
then
echo "a01.sh"
fi
# b01.sh存在并且有执行的权限
if [ -x b01.sh ]
then
echo "-x b01.sh"
fi
9.Shell流程控制-if
if [ $1 -ge 10 ]
then
echo "$1 >= 10"
elif [ $1 -ge 5 ]
then
echo "$1 >= 5"
else
echo "into else"
fi
10.Shell流程控制-case
case $1 in
"1")
echo "1"
;;
"2")
echo "2"
;;
*) # 匹配所有
echo "~"
;;
esac
11.Shell循环-for
#!/bin/bash
for i in "$*" # $*参数是一个整体
do
echo "num=$i"
done
echo "======="
for j in "$@" # $@参数不是一个整体
do
echo "num=$j"
done
echo "-------"
SUM=0
for ((k=0;k<100;k++))
do
SUM=$[$SUM+$k]
done
echo "end num is $SUM"
# 输出
num=10 20 30
=======
num=10
num=20
num=30
-------
end num is 4950
12.Shell循环-while
#!/bin/bash
SUM=0
i=0
while [ $i -lt $1 ]
do
SUM=$[$SUM+i]
i=$[$i+1]
done
echo "end $SUM"
13.Shell控制台输入
- read -p,-p,输出提示信息;-t 10,10秒没有输入,就不在等待。
- Shell实例。
#!/bin/bash
read -p "请输入一个数=" NUM
echo "num=$NUM"
read -t 10 -p "请输入第二个数=" NUM2 # 10秒没有输入,就不等待了。
echo "num2=$NUM2"
14.Shell函数-系统函数
- basename,返回文件名。
[root@localhost tmp]# basename /tmp/a01/b01/c01/1.txt
1.txt
[root@localhost tmp]# basename /tmp/a01/b01/c01/1.txt .txt
1
# basename /tmp/a01/b01/c01/1.txt .txt # 返回文件名,去掉.txt后的结果
- dirname,返回文件的目录。
[root@localhost tmp]# dirname /tmp/a01/b01/c01/1.txt
/tmp/a01/b01/c01
15.Shell函数-自定义函数
#!/bin/bash
function f1() # 定义一个函数
{
echo "f1 start"
SUM=$1+$2
return $[$SUM];
}
# main函数可以作为shell函数的入口
main()
{
echo "==start=="
SUM=$(f1 1 2)
# $SUM获取了函数f1,echo "f1 start"输出的结果
echo "==end==$SUM,$?" # 获取返回值要通过 $?,$?可以获取上一个命令执行的结果。
}
main
# 输出
==start==
==end==f1 start,3
16.Shell数据库备份脚本
#/bin/bash
# 备份的路径
BACKUP=/data/backup/db
#当前时间作为文件名
DATETIME=$(date +%Y_%m_%d_%H%M%S)
echo ${DATETIME}
echo "start $BACKUP/$DATETIME"
# 主机
HOST=localhost
# 用户名
DB_USER=root
# 密码
DB_PWD=123456
# 备份数据库名
DATABASE=test
# 不存在$BACKUP/$DATETIME,就去创建。
[ ! -d "$BACKUP/$DATETIME" ] && mkdir -p "$BACKUP/$DATETIME"
# 执行MySQL备份数据库的指令,只用gzip对文件进行压缩。
mysqldump -h${HOST} -u${DB_USER} -p${DB_PWD} -B $DATABASE | gzip > $BACKUP/$DATETIME/$DATETIME.sql.gz
17.定时执行Shell脚本
- crontab -e。
- */1 * * * * backup.sh。