作者:Chancel, 更新:2019 Dec 05, 字数:6594, 已阅:722
服务器上的备份脚本是好几年前写的,前段时间发现不工作了,准备检修下,简单看了下,这语法写的实在是太糟糕了(练习时长2年半的bug练习生涯过后果然看不起以前写的bug了),正好最近打算学习一下Bash Shell脚本的语法,就趁着这个机会学习下
bash?zsh?shell?都是什么?
Unix shell,引用wiki的说明
A Unix shell is a command-line interpreter or shell that provides a command line user interface for Unix-like operating systems. The shell is both an interactive command language and a scripting language, and is used by the operating system to control the execution of the system using shell scripts.
Users typically interact with a Unix shell using a terminal emulator; however, direct operation via serial hardware connections or Secure Shell are common for server systems. All Unix shells provide filename wildcarding, piping, here documents, command substitution, variables and control structures for condition-testing and iteration.
Unix shell是一个命令行解释器或shell,为类Unix操作系统提供命令行用户界面。
shell既是交互式命令语言又是脚本语言,操作系统使用它来控制使用shell脚本执行系统。 用户通常使用终端仿真器与Unix shell进行交互; 但是,通过串行硬件连接或Secure Shell直接操作对于服务器系统是常见的。 所有Unix shell都提供文件名通配符,管道,这里的文档,命令替换,变量和控制结构,用于条件测试和迭代。
简单讲就是Shell是一种命令语言 Shell目前主要有两大主流流派
大部分Linux发行版都是预设bash环境,bash是shell的一种,shell是一种统称符合其语法规则语言的简称
快速的看了下Bash的语法,看完很快,但教程网站好像都是写给新手看的,很多地方有经验的程序员根本不需要唠嗑那么多,这里我把语法点跟例子整理出来以供参考 脚本一般有开头标记来告诉环境需要什么脚本解释器,linux下script大部分情况下都是由bash解释器来执行的
#!/bin/bash
echo "Hello World !"
如何执行它?保存为一个hello.sh文件,赋予权限,并执行
chmod +x hello.sh
# 调用1. 使用指定解释器执行
/bin/bash hello.sh
# 调用2. 因为文件开头已经写了执行器类型,直接调用(./指当前目录,如有不理解请自行搜索)
./hello.sh
看看变量的创建调用与传递
#!/bin/bash
pick_hero="superman"
# 使用1. 不带花括号
echo $pick_hero is me
# 使用2. 带花括号(推荐写法)
echo ${pick_hero} is me
变量命名规则
变量其他写法一览
#!/bin/bash
myName="chancel"
# 设置只读,如无设置只读则变量可以无限次重复定义
readonly myName
mybook="None"
# 删除变量
unset myBook
# 拼接字符串
str01="hello"
str02="world"
echo ${str01}" "${str02}
# 定义数组
myArray = ("x" "y" "z")
echo $(myArray[0]) #取出x元素
echo ${myArray[×]} #取出所有元素
echo ${myArray[@]} #取出所有元素
# 遍历1
for var in ${myArray[@]}
do
echo $var
done
# 遍历2
for i in "${!myArray[@]}"
do
printf "%s\t%s\n" "$i" "${myArray[$i]}"
done
# 遍历3
i=0
while [ $i -lt ${#myArray[@]}]
do
echo ${myArray[$i]}
let i++
done
我们经常使用下面这种方法调用脚本
./xswl.sh -who chancel -why cxk
这种做法一般需要检查用户输入,下面是一个完整的方法
#!/bin/bash -e
show_help() {
echo "$0 [-h|-?|--help] [--who me] [--why hhh]"
echo "-h|-?|--help 显示帮助"
echo "--who 输入你是谁"
echo "--why 为什么笑"
}
while [[ $# -gt 0 ]]; do
case $1 in
-h | -\? | --help)
show_help
exit 0
;;
--who)
WHO="${2}"
shift
;;
--why)
WHY="${2}"
shift
;;
*)
echo -e "Error: $0 invalid option '$1'\nTry '$0 --help' for more information.\n" >&2
exit -1
;;
esac
shift
done
调用效果
$ ./xswl.sh -h
./xswl.sh [-h|-?|--help] [--who me] [--why hhh]
-h|-?|--help 显示帮助
--who 输入你是谁
--why 为什么笑
bash是如何控制流程的,参考下面的例子 if-else规则
if condition
then
command1
command2
...
commandN
fi
if-elseif-else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
一个简单的例子
#!/bin/bash -e
x=100
y=200
if [ $x == $y]
then
echo "x = y"
elif [ $x -gt $y ]
then
echo "x > y"
else
echo "x < y"
上面涉及到运算符,bash的运算符相对简单
参数 | 说明 |
---|---|
-eq | = |
-ne | != |
-gt | > |
-ge | >= |
-lt | =< |
-le | <= |
-z(字符串) | 字符串长度为零 |
-n(字符串) | 字符串长度不为零 |
下面是例子
#!/bin/bash
# 加减乘除运算
x=100
y=200
$z=$[x+y] #这语法有点奇怪,且实测等号两侧不可空格(写惯了c#可能很不习惯这种写法)
echo $z
# 字符串判断
x="hello"
y="hallo"
if test $x = $y
then
echo "字符串内容相同"
else
echo "字符串内容不同"
fi
到这写一个最基础的服务器备份脚本知识点基本都齐了,如果对其他语法点还感兴趣,可以参考下面进行学习
日常常见的语法还有下面这些
我的需求主要有以下2点
程序思路
于是经过上面的学习以及备份思路,你可以得到以下这份脚本,里面的所有知识点基本都在上面提到了,只有date函数没有提到(这个比较复杂,请自行搜索相关资料参阅)
#!/bin/bash
# author:chancel
# url:www.chancel.cn
show_help() {
echo "$0 [-h|-?|--help] [--temp /tmp/_backup] [--target /opt/backup/] [--dbuser root] [--dbpasswd passwd] [--extra /opt]"
echo "-h|-?|--help 显示帮助"
echo "--temp 设置备份文件时的缓存目录"
echo "--target 设置备份文件的目标(存放)路径"
echo "--dbuser 设置mysql数据库用户名称"
echo "--dbpasswd 设置mysql数据库用户密码"
echo "--extra 额外需要备份的目录,以空格分开不同目录"
}
while [[ $# -gt 0 ]]; do
case $1 in
-h | -\? | --help)
show_help
exit 0
;;
--temp)
temp="${2}"
shift
;;
--target)
target="${2}"
shift
;;
--dbuser)
dbuser="${2}"
shift
;;
--dbpasswd)
dbpasswd="${2}"
shift
;;
--extra)
extra="${2}"
shift
;;
--)
shift
break
;;
*)
echo -e "错误: $0 无效操作 '$1'\n可输入命令 '$0 --help' 获取更多帮助.\n" >&2
exit -1
;;
esac
shift
done
echo "创建必要的文件夹"
mysql_backup_dir=$temp'/mysql_backup'
mkdir -p $mysql_backup_dir
new_backup_file_path=$temp"/`date +%Y%m%d`.tar.gz"
old_backup_file_path=$target"/`date -d -1day +%Y%m%d`.tar.gz"
echo "备份mysql数据库"
databases=`mysql -u$dbuser -p$dbpasswd -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`
for db in $databases; do
if [[ "$db" != "sentry" ]] && [[ "$db" != "information_schema" ]] && [[ "$db" != "performance_schema" ]] && [[ "$db" != "mysql" ]] && [[ "$db" != _* ]] ; then
echo "正在导出数据库$db"
mysqldump -u$dbuser -p$dbpasswd --databases $db > $mysql_backup_dir'/'`date +%Y%m%d`-$db.sql
fi
done
echo "正在删除上一次产生的备份包"
rm -f $old_backup_file_path
echo "创建备份文件"$new_backup_file_path
tar -zcvf $new_backup_file_path $mysql_backup_dir $extra
mv $new_backup_file_path $target
echo "删除临时文件夹"$temp
rm -rf $temp
echo "备份结束"
参考这份文档,根据你的需要自定修改你就可以快速得到一份备份脚本