96.并发备份数据库
97.打印三角形
98.截取字符串
99.修改文本格式
100.自定义rm
并发备份数据库
题目要求
需求背景:
领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。
核心要点
通过命名管道FIFO来实现
exec 100<>test.fifo #把100描述符和test.fifo绑定在一起
代码
#!/bin/bash
#这个脚本用来并发备份数据库
##假设100个库的库名、host、port以及配置文件路径存到了一个文件里,文件名字为/tmp/databases.list
##格式:db1 10.10.10.2 3308 /data/mysql/db1/my.cnf
##备份数据库使用xtrabackup(由于涉及到myisam,命令为inoobackupex)
exec &> /tmp/mysql_bak.log
if ! which innobackupex &>/dev/nll
then
echo "安装xtrabackup工具"
rpm -ivh http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm && \
yum install -y percona-xtrabackup-24
if \[ $? -ne 0 \]
then
echo "安装xtrabackup工具出错,请检查。"
exit 1
fi
fi
bakdir=/data/backup/mysql
bakuser=vyNctM
bakpass=99omeaBHh
function bak_data {
db_name=$1
db_host=$2
db_port=$3
cnf=$4
\[ -d $bakdir/$db\_name \] || mkdir -p $bakdir/$db\_name
innobackupex --defaults-file=$4 --host=$2 --port=$3 --user=$bakuser --password=$bakpass $bakdir/$1
if \[ $? -ne 0 \]
then
echo "备份数据库$1出现问题。"
fi
}
fifofile=/tmp/$$
mkfifo $fifofile
exec 1000<>$fifofile
thread=10 #多少并发量,就要写入多少个空格
for ((i=0;i<$thread;i++))
do
echo >&1000
done
cat /tmp/databases.list | while read line
do
read -u1000
{
bak_data \`echo $line\`
echo >&1000
} &
done
wait
exec 1000>&-
rm -f $fifofile
打印三角形
题目要求
之前咱们打印过正方形,也打印过乘法口诀,那今天来打印一个三角形(正三角形,元素用*表示)。
核心要点
正三角形的元素排列,如果边长为5个*,在shell终端显示该正三角形的话,需要用5行,第一个行应该先打印4个空格,然后再打印‘’,第二行先打印三个空格,然后再打印“”,一直到第5行打印0个空格
代码
#!/bin/bash
#这个脚本用来打印三角形
while true
do
read -p "please input the lenth: " n
if \[ -z $n \]
then
echo "要输入一个数字。"
continue
else
n1=\`echo $n|sed 's/\[0-9\]//g'\`
if \[ -n "$n1" \]
then
echo "你输入的不是纯数字,重新输入。"
continue
else
break
fi
fi
done
for i in \`seq 1 $n\`
do
j=$\[$n-$i\]
for m in \`seq $j\`
do
echo -n " "
done
for p in \`seq 1 $i\`
do
echo -n "* "
done
echo
done
截取字符串
题目要求
利用你学过的知识点,想办法根据要求截取出字符。
字符串var=http://www.aaa.com/root/123.htm
2.取出123.htm
4.取出http:
5.取出http://
6.取出root/123.htm
7.取出123
核心要点
grep/sed/awk
代码
#!/bin/bash
#这个脚本用来截取字符串
var=http://www.aaa.com/root/123.htm
echo "1.取出www.aaa.com/root/123.htm"
echo $var |awk -F '//' '{print $2}'
echo "2.取出123.htm"
echo $var |awk -F '/' '{print $5}'
echo "3.取出http://www.aaa.com/root"
echo $var |sed 's#/123.htm##'
echo "4.取出http:"
echo $var |awk -F '//' '{print $1}'
echo "5.取出http://"
echo $var |awk -F 'www' '{print $1}'
echo "6.取出root/123.htm"
echo $var |awk -F 'com/' '{print $2}'
echo $var |awk -F '/' '{print $4"/"$5}'
echo "7.取出123"
echo $var |sed 's/\[^0-9\]//g'
修改文本格式
题目要求
请把下面的字符串:
zhangsan
y97JbzPru
lisi
5JhvCls6q
xiaowang
Nnr8qt2Ma
laoma
iqMtvC02y
zhaosi
9fxrb4sJD
改为如下:
zhangsan:y97JbzPru
lisi:5JhvCls6q
xiaowang:Nnr8qt2Ma
laoma:iqMtvC02y
zhaosi:9fxrb4sJD
核心要点
奇数,偶数行
sed 'N;s/\n/:/' test3.txt
代码
#!/bin/bash
#这个脚本用来格式化文本
n=\`wc -l test3.txt|awk '{print $1}'\`
n2=$\[$n/2\]
for i in \`seq 1 $n2\`
do
i2=$\[$i*2\]
j=$\[$i2-1\]
l1=\`sed -n "$i2"p test3.txt\`
l2=\`sed -n "$j"p test3.txt\`
echo $l2:$l1
done
自定义rm
题目要求
linux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:
- 简单
假设有一个大的分区/data/,每次删除文件或者目录之前,都要先在/data/下面创建一个隐藏目录,以日期/时间命名,比如/data/.201703271012/,然后把所有删除的文件同步到该目录下面,可以使用rsync -R 把文件路径一起同步
- 复杂
不知道哪个分区有剩余空间,在删除之前先计算要删除的文件或者目录大小,然后对比系统的磁盘空间,如果够则按照上面的规则创建隐藏目录,并备份,如果没有足够空间,要提醒用户没有足够 的空间备份并提示是否放弃备份,如果用户选择y,则直接删除文件或者目录,如果选择n,则提示未删除,然后退出脚本。
代码
1. 简单
#!/bin/bash
#这个脚本用来自定义rm
filename=$1
big_filesystem=/data/
if \[ ! -e $1 \]
then
echo "$1 不存在,请使用绝对路径"
exit
fi
d=\`date +%Y%m%d%H%M\`
read -p "Are U sure delete the file or directory $1? y|n: " c
case $c in
y|Y)
mkdir -p $big\_filesystem/.$d && rsync -aR $1 $big\_filesystem/.$d/$1 && /bin/rm -rf $1
;;
n|N)
exit 0
;;
*)
echo "Please input 'y' or 'n'."
;;
esac
2.复杂
#!/bin/bash
#这个脚本用来自定义rm
#!/bin/bash
filename=$1
if \[ ! -e $1 \]
then
echo "$1 不存在,请使用绝对路径"
exit
fi
d=\`date +%Y%m%d%H%M\`
f_size=\`du -sk $1|awk '{print $1}'\`
disk_size=\`LANG=en; df -k |grep -vi filesystem|awk '{print $4}' |sort -n |tail -n1\`
big_filesystem=\`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'\`
if \[ $f\_size -lt $disk\_size \]
then
read -p "Are U sure delete the file or directory: $1? y|n: " c
case $c in
y|Y)
mkdir -p $big\_filesystem/.$d && rsync -aR $1 $big\_filesystem/.$d/$1 && /bin/rm -rf $1
;;
n|N)
exit 0
;;
*)
echo "Please input 'y' or 'n'."
;;
esac
else
echo "The disk size is not enough to backup the files $1."
read -p "Do you want to delete $1? y|n: " c
case $c in
y|Y)
echo "It will delete $1 after 5 seconds whitout backup."
for i in \`seq 1 5\`; do echo -ne ". "; sleep 1;done #停顿5秒,每一秒打印一个点 echo -n 不换行
echo
/bin/rm -rf $1
;;
n|N)
echo "It will not delete $1."
exit 0
;;
*)
echo "Please input 'y' or 'n'."
;;
esac
fi