一、背景
在之前的博客 【Git学习–>如何通过Shell脚本实现 监控Gitlab备份整个过程并且通过邮件通知得到备份结果?】 里面,我已经详细记录了每天的自动备份与清理过期备份文件的工作。
1、每天凌晨2点在Gitlab服务器上执行Gitlab备份功能。
2、每天凌晨3点在Gitlab服务器上执行scp命令将最新的Gitlab备份文件复制到远程的文件备份服务器。
3、每天凌晨4点在远程的文件备份服务器上检测备份文件的时间,自动删除超过7天的备份文件。
这个脚本从8月18日开始运行,到12月12日一直都是正常运行的,可是到12月13日开始出现在执行第二条命令的时候出现了失败的情况,到今天已经连续出现4天了。
一开始我收到这个邮件的时候,我自己手动触发scp脚本去执行备份操作,发现都是正常的。
然后我怀疑
- 1、是不是第一步本地备份还没有执行完,第二步备份到远程服务器的操作就开始执行了?
- 2、是不是凌晨3点的时候是不是在这台Linux服务器上有其他人的脚本影响了我的脚本执行?
- 3、是不是凌晨3点的时候,这台Linux服务器上面的网络突然不通了?
好吧,关于第一点我查看了本地备份的日志
root@ubuntu4146:/data/gitlabData/backups# cat log/backup_2017-12-16.log Gitlab auto backup at local server, start at 2017-12-16 02:00:02--------------------------------------------------------------------------------------------------------------Success!----------------------------------------Gitlab auto backup at local server, end at 2017-12-16 02:29:35root@ubuntu4146:/data/gitlabData/backups#
发现第一步的本地备份日志只执行了半个小时在凌晨2点29分就备份完毕了,而第二步备份到远程服务器需要3点钟才开始执行,因此这个怀疑点被pass掉了。
关于怀疑点2和怀疑点3,问了本部门其他同事以及网络技术部门的人,都说没有相关的影响因素,没办法这个问题得解决啊!每天晚上的定时任务都失败了,然后早上来公司收到邮件之后我手动去执行该脚本又是百分之百成功,怪哉怪哉!
不过没有日志,其他同事都不会承认是他们的问题,当然也不一定是他们的问题。一切都要通过日志来查看第二步备份过程中,到底发生了什么事情。因此我需要在之前的基础上,把整个备份过程的日志都记录下来。
但是诸如 scp 这样的命令,打印在屏幕上的东西没法直接通过重定向来保存,因为它的输出并不是标准输出,那我要搞保存 scp 的日志怎么办呢?
通过查询资料,发现了script命令可以实现该功能,下面就让我们一起来学习学习script命令。
二、script命令简介
当你在终端或控制台上工作时,你可能想记录下自己做了些什么。这种记录可以看成是保存了终端痕迹的文档。假设你跟一些Linux管理员同时在系统上干活。或者说你让别人远程到你的服务器。你就会想记录下终端发生过什么。要实现它,你可以使用script命令。
2.1 什么script命令
script 是一个神奇命令,可以使用script工具记录用户在当前终端的所有的操作,已经输出到屏幕的内容。将这些信息保存到指定的文本文件中。
也就是说,script命令在你需要记录或者存档终端活动时可能很有用,记录文件会存储为文本文件,所以可以很方便地用文本编辑器打开。
在使用script命令将终端的会话过程录制下来之后,可以使用 scriptreplay将其录制的结果播放给他人观看。
script 的好处就在于你在终端中的所有操作、敲过的命令和打印出的结果它都可以原原本本地进行录制。可以应用于教学、演示、审计。
2.2 script命令操作
使用 script --help
命令来查看 script命令的用法
root@ubuntu4146:/# script --helpUsage: script [options] [file]Options: -a, --append append the output -c, --command <command> run command rather than interactive shell -r, --return return exit code of the child process -f, --flush run flush after each write --force use output file even when it is a link -q, --quiet be quiet -t, --timing[=<file>] output timing data to stderr (or to FILE) -V, --version output version information and exit -h, --help display this help and exitroot@ubuntu4146:/#
2.2.1 [file]选项
- 1、当file为空时,操作内容将记录到当前目录中名称为typescript的文本文件中。
例如,我们直接输入script,不加file选项的时候,开始记录终端的操作行为,并将操作内容输出到当前目录的typescript中,如下图所示:
root@ubuntu4146:/# scriptScript started, file is typescriptroot@ubuntu4146:/#
生成的默认文件为 typescript ,如下图所示:
- 2、如果指定file,那么将把终端的操作内容记录到file文件中。
root@ubuntu4146:/# exitexitScript done on 2017年12月16日 星期六 11时24分06秒root@ubuntu4146:/# script script_ouyangpeng.hisScript started, file is script_ouyangpeng.hisroot@ubuntu4146:/# lltotal 660drwxr-xr-x 26 root root 4096 12月 16 11:25 ./drwxr-xr-x 26 root root 4096 12月 16 11:25 ../drwxr-xr-x 2 root root 4096 12月 15 16:23 bin/drwxr-xr-x 3 root root 4096 11月 3 2015 boot/drwxr-xr-x 3 root root 4096 12月 10 2015 build/drwxr-xr-x 8 root root 4096 8月 17 11:38 data/drwxr-xr-x 15 root root 4200 12月 5 09:54 dev/drwxr-xr-x 130 root root 12288 12月 15 16:24 etc/drwxr-xr-x 4 root root 4096 11月 20 2016 home/lrwxrwxrwx 1 root root 33 11月 3 2015 initrd.img -> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x 22 root root 4096 1月 3 2017 lib/drwxr-xr-x 2 root root 12288 1月 3 2017 lib32/drwxr-xr-x 2 root root 4096 1月 3 2017 lib64/drwxr-xr-x 2 root root 4096 1月 3 2017 libx32/drwx------ 2 root root 16384 11月 3 2015 lost+found/drwxr-xr-x 3 root root 4096 11月 3 2015 media/drwxr-xr-x 2 root root 4096 4月 11 2014 mnt/drwxr-xr-x 4 root root 4096 8月 10 11:06 opt/dr-xr-xr-x 461 root root 0 12月 5 09:54 proc/drwx------ 8 root root 4096 12月 16 10:00 root/drwxr-xr-x 24 root root 840 12月 16 11:26 run/drwxr-xr-x 2 root root 4096 12月 15 16:23 sbin/-rw-r--r-- 1 root root 0 12月 16 11:25 script_ouyangpeng.hisdrwxr-xr-x 3 root root 4096 11月 16 2016 srv/dr-xr-xr-x 13 root root 0 12月 16 11:21 sys/drwxrwxrwt 8 root root 552960 12月 16 11:25 tmp/-rw-r--r-- 1 root root 2217 12月 16 11:24 typescriptdrwxr-xr-x 15 root root 4096 11月 4 2015 usr/drwxr-xr-x 14 root root 4096 2月 24 2017 var/lrwxrwxrwx 1 root root 30 11月 3 2015 vmlinuz -> boot/vmlinuz-3.19.0-25-genericroot@ubuntu4146:/#
如上代码所示,我们先exit掉第一个script命令,然后我们开始第二个script命令,并且直接file选项为 script_ouyangpeng.his。这样就会在当前目录下生成一个script_ouyangpeng.his文件。
2.2.2 [options]选项
root@ubuntu4146:/data/gitlabData/backups# script --helpUsage: script [options] [file]Options: -a, --append append the output -c, --command <command> run command rather than interactive shell -r, --return return exit code of the child process -f, --flush run flush after each write --force use output file even when it is a link -q, --quiet be quiet -t, --timing[=<file>] output timing data to stderr (or to FILE) -V, --version output version information and exit -h, --help display this help and exit
script有很多 option 可选项,下面我们来介绍一下这几个 option。
- -a 选项 ,在现有输出录制的文件的内容上追加新的内容
- -c选项 ,后面可以加上需要执行的命令,而不是交互式shell上执行的命令
- -r选项 , 子进程中返回退出代码
- -f选项 , 如果需要在输出到日志文件的同时,也可以查看日志文件的内容,可以使用 -f 参数。PS:可以用于教学,两个命令行接-f可以实时演示
- -q选项 ,可以使script命令以静默模式运行
- -t选项,指明输出录制的时间数据
- -V选项,输出script的版本信息,然后退出
- -h选项,输出script的help信息,然后退出
现在我们来使用一下这几个option可选项。
先从简单的来
- script -V 选项
root@ubuntu4146:/# script -Vscript from util-linux 2.20.1
- script -h 选项
root@ubuntu4146:/# script -hUsage: script [options] [file]Options: -a, --append append the output -c, --command <command> run command rather than interactive shell -r, --return return exit code of the child process -f, --flush run flush after each write --force use output file even when it is a link -q, --quiet be quiet -t, --timing[=<file>] output timing data to stderr (or to FILE) -V, --version output version information and exit -h, --help display this help and exitroot@ubuntu4146:/#
- script -q 选项
root@ubuntu4146:/# scriptScript started, file is typescriptroot@ubuntu4146:/# exitexitScript done, file is typescriptroot@ubuntu4146:/# script -qroot@ubuntu4146:/# exitexitroot@ubuntu4146:/#
- script -a 选项
我们先使用 script script_ouyangpeng.his
命令来记录,然后敲一个echo "Hello OuyangPeng"
来输出一句话,接着使用exit
命令退出script记录。
root@ubuntu4146:/# script script_ouyangpeng.his Script started, file is script_ouyangpeng.hisroot@ubuntu4146:/# echo "Hello OuyangPeng"Hello OuyangPengroot@ubuntu4146:/# exitexitScript done, file is script_ouyangpeng.his
现在我们可以查看下 script_ouyangpeng.his 文件中的内容
root@ubuntu4146:/# script script_ouyangpeng.his Script started, file is script_ouyangpeng.hisroot@ubuntu4146:/# echo "Hello OuyangPeng"Hello OuyangPengroot@ubuntu4146:/# exitexitScript done, file is script_ouyangpeng.hisroot@ubuntu4146:/# vim script_ouyangpeng.his root@ubuntu4146:/# more script_ouyangpeng.his Script started on 2017年12月16日 星期六 11时47分13秒root@ubuntu4146:/# echo "Hello OuyangPeng"Hello OuyangPengroot@ubuntu4146:/# exitexitScript done on 2017年12月16日 星期六 11时47分37秒root@ubuntu4146:/#
如上图所示,记录文件中的内容完完全全将我们的所有操作都记录下来了。
现在我们使用 script -a 选项 在 script_ouyangpeng.his 记录文件上追加内容,如下所示:
root@ubuntu4146:/# script -a script_ouyangpeng.his Script started, file is script_ouyangpeng.hisroot@ubuntu4146:/# echo "Hello OuyangPeng , using the option -a "Hello OuyangPeng , using the option -a root@ubuntu4146:/# exitexitScript done, file is script_ouyangpeng.hisroot@ubuntu4146:/#
命令执行完之后,我们来查看下 script_ouyangpeng.his 文件内容
- script -t 选项
root@ubuntu4146:/# script -t 2>script_ouyangpeng.time -a script_ouyangpeng.his Script started, file is script_ouyangpeng.hisroot@ubuntu4146:/# echo "hello script -t "hello script -t root@ubuntu4146:/# exitexitScript done, file is script_ouyangpeng.hisroot@ubuntu4146:/#
选项-t用于存储时序文件,这里导入到stderr,再重定向到script_ouyangpeng.time,
选项-a用于将命令输出信息,追加到script_ouyangpeng.his文件。
这样录制视屏就很方便啦,而且这两个文件很小,可以拷贝到需要播放的机器上进行播放。
script_ouyangpeng.time文件内容如下
root@ubuntu4146:/# cat script_ouyangpeng.time 0.687691 420.011893 14.882787 10.239823 10.143958 10.144012 10.175839 10.896221 10.104910 10.431160 31.080299 30.087901 30.136447 30.135804 30.176703 30.135228 30.312291 30.199814 30.192203 30.151796 30.352006 30.192111 36.896969 30.975974 30.176020 30.344094 38.946105 620.415012 13.224206 10.264114 10.128965 10.391474 8
script_ouyangpeng.his文件如下
root@ubuntu4146:/# cat script_ouyangpeng.his Script started on 2017年12月16日 星期六 11时47分13秒root@ubuntu4146:/# echo "Hello OuyangPeng"Hello OuyangPengroot@ubuntu4146:/# exitexitScript done on 2017年12月16日 星期六 11时47分37秒Script started on 2017年12月16日 星期六 11时53分45秒root@ubuntu4146:/# echo "Hello OuyangPeng , using the option -a "Hello OuyangPeng , using the option -a root@ubuntu4146:/# exitexitScript done on 2017年12月16日 星期六 11时54分29秒Script started on 2017年12月16日 星期六 12时05分35秒root@ubuntu4146:/# echo "hello script -t "hello script -t root@ubuntu4146:/# exitexitScript done on 2017年12月16日 星期六 12时06分07秒root@ubuntu4146:/#
- script -f 选项
在第一个命令框输入
root@ubuntu4146:/# script -f -t 2>script_ouyangpeng_f.time -a script_ouyangpeng_f.his Script started, file is script_ouyangpeng_f.hisroot@ubuntu4146:/# echo "hello ouyangpeng script -f "hello ouyangpeng script -f root@ubuntu4146:/# echo "script -f second step echo "script -f second step echo root@ubuntu4146:/#
使用script -f 实时刷新数据,记录文件分别为 script_ouyangpeng_f.time 和 script_ouyangpeng_f.his
现在打开第二个命令框,输入命令
scriptreplay script_ouyangpeng_f.time script_ouyangpeng_f.his
敲完命令回车后,终端会一步一步的回放在第一个命令框输入的记录。如下所示:
具体的动画效果,读者可以自己实际操作体验,这里就不放gif图片了。
- script -c 选项
root@ubuntu4146:/# script -a "script_ouyangpeng_c.his" -c "ls -h"Script started, file is script_ouyangpeng_c.hisbin dev lib lost+found proc script_ouyangpeng_c.his script_ouyangpeng.time usrboot etc lib32 media root script_ouyangpeng_f.his srv varbuild home lib64 mnt run script_ouyangpeng_f.time sys vmlinuzdata initrd.img libx32 opt sbin script_ouyangpeng.his tmpScript done, file is script_ouyangpeng_c.hisroot@ubuntu4146:/#
-c 后面,接上命令 ls -h
,然后将记录追加到script_ouyangpeng_c.his文件中
现在我们来查看 script_ouyangpeng_c.his文件
root@ubuntu4146:/# cat script_ouyangpeng_c.his Script started on 2017年12月16日 星期六 12时49分16秒bin dev lib lost+found proc script_ouyangpeng_c.his script_ouyangpeng.time usrboot etc lib32 media root script_ouyangpeng_f.his srv varbuild home lib64 mnt run script_ouyangpeng_f.time sys vmlinuzdata initrd.img libx32 opt sbin script_ouyangpeng.his tmpScript done on 2017年12月16日 星期六 12时49分16秒root@ubuntu4146:/#
2.2.3 退出script
要退出记录活动,我们可以在终端中按下Ctrl+D,或者输入exit。在退出script前,你会发现记录文件的大小为0 Kb,而在退出之后,文件大小会发生改变。
root@ubuntu4146:/# script -a "script_ouyangpeng_exit.his"Script started, file is script_ouyangpeng_exit.hisroot@ubuntu4146:/# lltotal 680drwxr-xr-x 26 root root 4096 12月 16 12:53 ./drwxr-xr-x 26 root root 4096 12月 16 12:53 ../drwxr-xr-x 2 root root 4096 12月 15 16:23 bin/drwxr-xr-x 3 root root 4096 11月 3 2015 boot/drwxr-xr-x 3 root root 4096 12月 10 2015 build/drwxr-xr-x 8 root root 4096 8月 17 11:38 data/drwxr-xr-x 15 root root 4200 12月 5 09:54 dev/drwxr-xr-x 130 root root 12288 12月 15 16:24 etc/drwxr-xr-x 4 root root 4096 11月 20 2016 home/lrwxrwxrwx 1 root root 33 11月 3 2015 initrd.img -> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x 22 root root 4096 1月 3 2017 lib/drwxr-xr-x 2 root root 12288 1月 3 2017 lib32/drwxr-xr-x 2 root root 4096 1月 3 2017 lib64/drwxr-xr-x 2 root root 4096 1月 3 2017 libx32/drwx------ 2 root root 16384 11月 3 2015 lost+found/drwxr-xr-x 3 root root 4096 11月 3 2015 media/drwxr-xr-x 2 root root 4096 4月 11 2014 mnt/drwxr-xr-x 4 root root 4096 8月 10 11:06 opt/dr-xr-xr-x 464 root root 0 12月 5 09:54 proc/drwx------ 8 root root 4096 12月 16 11:47 root/drwxr-xr-x 24 root root 840 12月 16 12:53 run/drwxr-xr-x 2 root root 4096 12月 15 16:23 sbin/-rw-r--r-- 1 root root 461 12月 16 12:49 script_ouyangpeng_c.his-rw-r--r-- 1 root root 0 12月 16 12:53 script_ouyangpeng_exit.his-rw-r--r-- 1 root root 176 12月 16 12:47 script_ouyangpeng_f.his-rw-r--r-- 1 root root 1460 12月 16 12:47 script_ouyangpeng_f.time-rw-r--r-- 1 root root 4312 12月 16 12:36 script_ouyangpeng.his-rw-r--r-- 1 root root 555 12月 16 12:36 script_ouyangpeng.timedrwxr-xr-x 3 root root 4096 11月 16 2016 srv/dr-xr-xr-x 13 root root 0 12月 16 11:21 sys/drwxrwxrwt 8 root root 552960 12月 16 12:50 tmp/drwxr-xr-x 15 root root 4096 11月 4 2015 usr/drwxr-xr-x 14 root root 4096 2月 24 2017 var/
在执行命令之后,还是 0 字节
root@ubuntu4146:/# echo "hello script exit"hello script exitroot@ubuntu4146:/# lltotal 680drwxr-xr-x 26 root root 4096 12月 16 12:53 ./drwxr-xr-x 26 root root 4096 12月 16 12:53 ../drwxr-xr-x 2 root root 4096 12月 15 16:23 bin/drwxr-xr-x 3 root root 4096 11月 3 2015 boot/drwxr-xr-x 3 root root 4096 12月 10 2015 build/drwxr-xr-x 8 root root 4096 8月 17 11:38 data/drwxr-xr-x 15 root root 4200 12月 5 09:54 dev/drwxr-xr-x 130 root root 12288 12月 15 16:24 etc/drwxr-xr-x 4 root root 4096 11月 20 2016 home/lrwxrwxrwx 1 root root 33 11月 3 2015 initrd.img -> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x 22 root root 4096 1月 3 2017 lib/drwxr-xr-x 2 root root 12288 1月 3 2017 lib32/drwxr-xr-x 2 root root 4096 1月 3 2017 lib64/drwxr-xr-x 2 root root 4096 1月 3 2017 libx32/drwx------ 2 root root 16384 11月 3 2015 lost+found/drwxr-xr-x 3 root root 4096 11月 3 2015 media/drwxr-xr-x 2 root root 4096 4月 11 2014 mnt/drwxr-xr-x 4 root root 4096 8月 10 11:06 opt/dr-xr-xr-x 458 root root 0 12月 5 09:54 proc/drwx------ 8 root root 4096 12月 16 11:47 root/drwxr-xr-x 24 root root 840 12月 16 12:53 run/drwxr-xr-x 2 root root 4096 12月 15 16:23 sbin/-rw-r--r-- 1 root root 461 12月 16 12:49 script_ouyangpeng_c.his-rw-r--r-- 1 root root 0 12月 16 12:53 script_ouyangpeng_exit.his-rw-r--r-- 1 root root 176 12月 16 12:47 script_ouyangpeng_f.his-rw-r--r-- 1 root root 1460 12月 16 12:47 script_ouyangpeng_f.time-rw-r--r-- 1 root root 4312 12月 16 12:36 script_ouyangpeng.his-rw-r--r-- 1 root root 555 12月 16 12:36 script_ouyangpeng.timedrwxr-xr-x 3 root root 4096 11月 16 2016 srv/dr-xr-xr-x 13 root root 0 12月 16 11:21 sys/drwxrwxrwt 8 root root 552960 12月 16 12:50 tmp/drwxr-xr-x 15 root root 4096 11月 4 2015 usr/drwxr-xr-x 14 root root 4096 2月 24 2017 var/lrwxrwxrwx 1 root root 30 11月 3 2015 vmlinuz -> boot/vmlinuz-3.19.0-25-genericroot@ubuntu4146:/#
这个时候,我们输入 exit 之后,再去查看文件大小
root@ubuntu4146:/# exitexitScript done, file is script_ouyangpeng_exit.hisroot@ubuntu4146:/# lltotal 688drwxr-xr-x 26 root root 4096 12月 16 12:53 ./drwxr-xr-x 26 root root 4096 12月 16 12:53 ../drwxr-xr-x 2 root root 4096 12月 15 16:23 bin/drwxr-xr-x 3 root root 4096 11月 3 2015 boot/drwxr-xr-x 3 root root 4096 12月 10 2015 build/drwxr-xr-x 8 root root 4096 8月 17 11:38 data/drwxr-xr-x 15 root root 4200 12月 5 09:54 dev/drwxr-xr-x 130 root root 12288 12月 15 16:24 etc/drwxr-xr-x 4 root root 4096 11月 20 2016 home/lrwxrwxrwx 1 root root 33 11月 3 2015 initrd.img -> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x 22 root root 4096 1月 3 2017 lib/drwxr-xr-x 2 root root 12288 1月 3 2017 lib32/drwxr-xr-x 2 root root 4096 1月 3 2017 lib64/drwxr-xr-x 2 root root 4096 1月 3 2017 libx32/drwx------ 2 root root 16384 11月 3 2015 lost+found/drwxr-xr-x 3 root root 4096 11月 3 2015 media/drwxr-xr-x 2 root root 4096 4月 11 2014 mnt/drwxr-xr-x 4 root root 4096 8月 10 11:06 opt/dr-xr-xr-x 465 root root 0 12月 5 09:54 proc/drwx------ 8 root root 4096 12月 16 11:47 root/drwxr-xr-x 24 root root 840 12月 16 12:55 run/drwxr-xr-x 2 root root 4096 12月 15 16:23 sbin/-rw-r--r-- 1 root root 461 12月 16 12:49 script_ouyangpeng_c.his-rw-r--r-- 1 root root 5283 12月 16 12:56 script_ouyangpeng_exit.his-rw-r--r-- 1 root root 176 12月 16 12:47 script_ouyangpeng_f.his-rw-r--r-- 1 root root 1460 12月 16 12:47 script_ouyangpeng_f.time-rw-r--r-- 1 root root 4312 12月 16 12:36 script_ouyangpeng.his-rw-r--r-- 1 root root 555 12月 16 12:36 script_ouyangpeng.timedrwxr-xr-x 3 root root 4096 11月 16 2016 srv/dr-xr-xr-x 13 root root 0 12月 16 11:21 sys/drwxrwxrwt 8 root root 552960 12月 16 12:50 tmp/drwxr-xr-x 15 root root 4096 11月 4 2015 usr/drwxr-xr-x 14 root root 4096 2月 24 2017 var/lrwxrwxrwx 1 root root 30 11月 3 2015 vmlinuz -> boot/vmlinuz-3.19.0-25-genericroot@ubuntu4146:/#
至此,script的基本用法已经讲解完毕了,接下来我们需要将script命令用于我们之前的实际场景中:跟踪整个备份文件的所有操作。
三、Script命令结合实际使用场景
3.1 先在终端执行script命令记录scp命令过程
先在终端敲个命令
root@ubuntu4146:/data/gitlabData/backups# script /data/gitlabData/backups/script_log/scp_2017-12-16.log -c "scp -v /data/gitlabData/backups/1513362071_2017_12_16_9.4.3_gitlab_backup.tar root@172.xxx.xxx.xxx:/root/gitlabDataBackup"
这个命令的意思,使用 script 命令记录我们的 scp命令执行的结果,执行记录文件保存在 /data/gitlabData/backups/script_log/scp_2017-12-16.log 文件中。
整个执行过程如下所示:
root@ubuntu4146:/data/gitlabData/backups# script /data/gitlabData/backups/script_log/scp_2017-12-16.log -c "scp -v /data/gitlabData/backups/1513362071_2017_12_16_9.4.3_gitlab_backup.tar root@172.xxx.xxx.xxx:/root/gitlabDataBackup"Script started, file is /data/gitlabData/backups/script_log/scp_2017-12-16.logExecuting: program /usr/bin/ssh host 172.xxx.xxx.xxx, user root, command scp -v -t /root/gitlabDataBackupOpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014debug1: Reading configuration data /etc/ssh/ssh_configdebug1: /etc/ssh/ssh_config line 19: Applying options for *debug1: Connecting to 172.xxx.xxx.xxx [172.xxx.xxx.xxx] port 22.debug1: Connection established.debug1: permanently_set_uid: 0/0debug1: identity file /root/.ssh/id_rsa type 1debug1: identity file /root/.ssh/id_rsa-cert type -1debug1: identity file /root/.ssh/id_dsa type -1debug1: identity file /root/.ssh/id_dsa-cert type -1debug1: identity file /root/.ssh/id_ecdsa type -1debug1: identity file /root/.ssh/id_ecdsa-cert type -1debug1: identity file /root/.ssh/id_ed25519 type -1debug1: identity file /root/.ssh/id_ed25519-cert type -1debug1: Enabling compatibility mode for protocol 2.0debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3debug1: match: OpenSSH_5.3 pat OpenSSH_5* compat 0x0c000000debug1: SSH2_MSG_KEXINIT sentdebug1: SSH2_MSG_KEXINIT receiveddebug1: kex: server->client aes128-ctr hmac-md5 nonedebug1: kex: client->server aes128-ctr hmac-md5 nonedebug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<3072<8192) sentdebug1: expecting SSH2_MSG_KEX_DH_GEX_GROUPdebug1: SSH2_MSG_KEX_DH_GEX_INIT sentdebug1: expecting SSH2_MSG_KEX_DH_GEX_REPLYdebug1: Server host key: RSA c8:d1:29:e8:ec:62:0c:6e:57:d5:3f:8a:25:cc:01:9cdebug1: Host '172.xxx.xxx.xxx' is known and matches the RSA host key.debug1: Found key in /root/.ssh/known_hosts:5debug1: ssh_rsa_verify: signature correctdebug1: SSH2_MSG_NEWKEYS sentdebug1: expecting SSH2_MSG_NEWKEYSdebug1: SSH2_MSG_NEWKEYS receiveddebug1: SSH2_MSG_SERVICE_REQUEST sentdebug1: SSH2_MSG_SERVICE_ACCEPT receiveddebug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,passworddebug1: Next authentication method: gssapi-keyexdebug1: No valid Key exchange contextdebug1: Next authentication method: gssapi-with-micdebug1: Unspecified GSS failure. Minor code may provide more informationNo Kerberos credentials availabledebug1: Unspecified GSS failure. Minor code may provide more informationNo Kerberos credentials availabledebug1: Unspecified GSS failure. Minor code may provide more informationdebug1: Unspecified GSS failure. Minor code may provide more informationNo Kerberos credentials availabledebug1: Next authentication method: publickeydebug1: Offering RSA public key: /root/.ssh/id_rsadebug1: Server accepts key: pkalg ssh-rsa blen 279debug1: key_parse_private2: missing begin markerdebug1: read PEM private key done: type RSAdebug1: Authentication succeeded (publickey).Authenticated to 172.xxx.xxx.xxx ([172.xxx.xxx.xxx]:22).debug1: channel 0: new [client-session]debug1: Requesting no-more-sessions@openssh.comdebug1: Entering interactive session.debug1: Sending environment.debug1: Sending env LANG = zh_CN.UTF-8debug1: Sending command: scp -v -t /root/gitlabDataBackupSending file modes: C0600 65384335360 1513362071_2017_12_16_9.4.3_gitlab_backup.tarSink: C0600 65384335360 1513362071_2017_12_16_9.4.3_gitlab_backup.tar1513362071_2017_12_16_9.4.3_gitlab_backup.tar 100% 61GB 110.8MB/s 09:23 scp: /root/gitlabDataBackup/1513362071_2017_12_16_9.4.3_gitlab_backup.tar: No space left on devicedebug1: channel 0: free: client-session, nchannels 1Script done, file is /data/gitlabData/backups/script_log/scp_2017-12-16.logroot@ubuntu4146:/data/gitlabData/backups#
script记录整个过程结束,文件传输百分百成功了。
去远程备份服务器查看,刚才的 1513362071_2017_12_16_9.4.3_gitlab_backup.tar 文件确实百分百传输成功了。
现在我们来看下 刚才 script命令的执行结果的文件,
从结果来看,整个过程使用script命令记录是没有问题的。因此我们下面来修改执行的远程备份文件的脚本文件,添加上添加script命令来记录scp的执行过程。
3.2 在脚本文件中添加script命令来记录scp的执行过程
上面在终端测试结果令人满意,现在我们来修改之前的 Gitlab自动备份到远程文件备份服务器的脚本 ,在脚本中 添加script命令来记录scp的执行过程。
之前的脚本文件 auto_backup_to_remote.sh 内容为
#!/bin/bash# gitlab 机房备份路径LocalBackDir=/data/gitlabData/backups# 远程备份服务器 gitlab备份文件存放路径RemoteBackDir=/root/gitlabDataBackup# 远程备份服务器 登录账户RemoteUser=root# 远程机房代码备份服务器 IP地址RemoteIP1=172.xxx.xxx.xxx#当前系统日期DATE=`date +"%Y-%m-%d"`#Log存放路径LogFile=$LocalBackDir/log/$DATE.log# 查找 本地备份目录下 时间为180分钟之内的,并且后缀为.tar的gitlab备份文件BACKUPFILE_SEND_TO_REMOTE=$(find /data/gitlabData/backups -type f -mmin -180 -name '*.tar*')#邮件写入的文件mailcontent=$LocalBackDir/mail/mailcontent_$DATEmailToUser=ouyangpeng的邮箱mailToUser1=领导1的邮箱mailToUser2=领导2的邮箱#新建日志文件touch $LogFile#追加日志到日志文件echo "Gitlab auto backup to remote server, start at $(date +"%Y-%m-%d %H:%M:%S")" > $LogFileecho "---------------------------------------------------------------------------" >> $LogFile# 输出日志,打印出每次scp的文件名echo "---------------------The file to scp to remote server is: $BACKUPFILE_SEND_TO_REMOTE-------------------------------" >> $LogFile#备份到 远程备份服务器 (办公室)#scp $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP2:$RemoteBackDir#备份到 远程机房代码备份服务器scp $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP1:$RemoteBackDir# $?符号显示上一条命令的返回值,如果为0则代表执行成功,其他表示失败if [ $? -eq 0 ];then #追加日志到日志文件 echo "-----------------------------------Success!----------------------------------------" >> $LogFile echo "Gitlab auto backup to remote server, end at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile #写Email的正文内容 > "$mailcontent" echo "GitLab Backup Daily Report, backup to remote server Success ! Please Check your Email and read the following log file" >> $mailcontent #读取mailcontent内容当做邮件正文 ,附件为Log文件 #cat $mailcontent | mail -s "Congratulation! GitLab backup to remote server Success Report." -t $mailToUser $mailToUser1 $mailToUser2 -A $LogFile #成功的话,只发送给我一个人即可,不需要发送给其他人 cat $mailcontent | mail -s "Congratulation! GitLab backup to remote server Success Report." $mailToUser -A $LogFileelse #追加日志到日志文件 echo "-----------------------------------Failed!---------------------------------------" >> $LogFile echo "Gitlab auto backup to remote server failed at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile #写Email的正文内容 > "$mailcontent" echo "GitLab Backup Daily Report,Backup to remote server Failed ! Please Check your Email and read the following log file !" >> $mailcontent #读取mailcontent内容当做邮件正文 ,附件为Log文件 cat $mailcontent | mail -s "Warning! GitLab Backup to remote server Failed Report." -t $mailToUser $mailToUser1 $mailToUser2 -A $LogFilefi
现在我们添加 script命令记录全程备份过程,修改后的脚本如下所示
#!/bin/bash# gitlab 机房备份路径LocalBackDir=/data/gitlabData/backups# 远程备份服务器 gitlab备份文件存放路径RemoteBackDir=/root/gitlabDataBackup# 远程备份服务器 登录账户RemoteUser=root# 远程机房代码备份服务器 IP地址RemoteIP1=172.xxx.xxx.xxx#当前系统日期DATE=`date +"%Y-%m-%d"`#Log存放路径LogFile=$LocalBackDir/log/$DATE.log#Script命令记录的存放路径和文件名ScriptLogFile=$LocalBackDir/script_log/$DATE.log# 查找 本地备份目录下 时间为180分钟之内的,并且后缀为.tar的gitlab备份文件BACKUPFILE_SEND_TO_REMOTE=$(find /data/gitlabData/backups -type f -mmin -180 -name '*.tar*')#邮件写入的文件mailcontent=$LocalBackDir/mail/mailcontent_$DATEmailToUser=ouyangpeng的邮箱mailToUser1=领导1的邮箱mailToUser2=领导2的邮箱#新建日志文件touch $LogFiletouch $SciptLogFile#追加日志到日志文件echo "Gitlab auto backup to remote server, start at $(date +"%Y-%m-%d %H:%M:%S")" > $LogFileecho "---------------------------------------------------------------------------" >> $LogFile# 输出日志,打印出每次scp的文件名echo "---------------------The file to scp to remote server is: $BACKUPFILE_SEND_TO_REMOTE-------------------------------" >> $LogFile#备份到 远程备份服务器 (办公室)#scp $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP2:$RemoteBackDir#备份到 远程机房代码备份服务器#scp $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP1:$RemoteBackDirscript -qa $ScriptLogFile -c" scp -v $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP1:$RemoteBackDir"# $?符号显示上一条命令的返回值,如果为0则代表执行成功,其他表示失败if [ $? -eq 0 ];then #追加日志到日志文件 echo "-----------------------------------Success!----------------------------------------" >> $LogFile echo "Gitlab auto backup to remote server, end at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile #写Email的正文内容 > "$mailcontent" echo "GitLab Backup Daily Report, backup to remote server Success ! Please Check your Email and read the following log file" >> $mailcontent #读取mailcontent内容当做邮件正文 ,附件为Log文件 #cat $mailcontent | mail -s "Congratulation! GitLab backup to remote server Success Report." -t $mailToUser $mailToUser1 $mailToUser2 -A $LogFile #成功的话,只发送给我一个人即可,不需要发送给其他人 cat $mailcontent | mail -s "Congratulation! GitLab backup to remote server Success Report." $mailToUser -A $LogFileelse #追加日志到日志文件 echo "-----------------------------------Failed!---------------------------------------" >> $LogFile echo "Gitlab auto backup to remote server failed at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile #写Email的正文内容 > "$mailcontent" echo "GitLab Backup Daily Report,Backup to remote server Failed ! Please Check your Email and read the following log file !" >> $mailcontent #读取mailcontent内容当做邮件正文 ,附件为Log文件 cat $mailcontent | mail -s "Warning! GitLab Backup to remote server Failed Report." -t $mailToUser $mailToUser1 $mailToUser2 -A $LogFilefi
修改如下:
1、定义一个 Script命令记录的存放路径和文件名
#Script命令记录的存放路径和文件名ScriptLogFile=$LocalBackDir/script_log/$DATE.log
2、新建刚才定义好的文件
touch $SciptLogFile
3、将 scp 命令 用 script包装一下,将整个执行过程记录下来
#备份到 远程机房代码备份服务器#scp $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP1:$RemoteBackDirscript -qa $ScriptLogFile -c" scp -v $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP1:$RemoteBackDir"
4、执行刚才的修改脚本
root@ubuntu4146:/data/gitlabData/backups# ./auto_backup_to_remote.sh
执行脚本
执行完毕
5、查看刚才 script命令执行的记录文件
root@ubuntu4146:/data/gitlabData/backups# more script_log/2017-12-16.log
执行进度百分比的日志
执行完毕的日志
四、总结
好啦,我们通过学习script命令,给scp命令增加了日志记录,现在我们等待明天早上的邮件结果,如果还是失败的话,我们就可以查看具体script命令记录下来的日志分析了。
具体结果如何,明天早上我们再继续分析!
今天是 2017-12-18 日,上班来查看下这两天的运行情况,如下所示
2017-12-17日和2017-12-18日的备份操作都是成功的,看来失败的原因还得等他失败才能够查看了。不过我们来看看这两天成功的情况下,整个备份过程的日志记录。
使用more命令来查看下 详细记录
root@ubuntu4146:/data/gitlabData/backups# more script_log/2017-12-17.log
整个过程没问题。
OK,过了几天发现邮件发送的都是成功的,如下图所示
实际上是有问题的,远程代码备份的服务器上,传输的文件大小和gitlab服务器上的备份文件不一样大。被裁剪了,如下图所示:
而远程备份服务器上 1513967001_2017_12_23_9.4.3_gitlab_backup.tar 只有23G
而gitlab服务器上 1513967001_2017_12_23_9.4.3_gitlab_backup.tar 有62G
通过查看我们之前使用 script记录下来的日志可以分析出问题所在
日志开头
root@ubuntu4146:/data/gitlabData/backups# more script_log/2017-12-22017-12-20.log 2017-12-21.log 2017-12-22.log 2017-12-23.log root@ubuntu4146:/data/gitlabData/backups# more script_log/2017-12-23.log Script started on 2017年12月23日 星期六 04时00分02秒
查看日志最后
1513967001_2017_12_23_9.4.3_gitlab_backup.tar 88% 54GB 111.5MB/s 01:07 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 89% 55GB 111.6MB/s 00:57 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 91% 56GB 111.7MB/s 00:48 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 93% 57GB 111.8MB/s 00:38 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 94% 58GB 111.6MB/s 00:29 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 96% 59GB 111.8MB/s 00:19 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 98% 60GB 111.8MB/s 00:10 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 99% 62GB 111.9MB/s 00:00 ETA1513967001_2017_12_23_9.4.3_gitlab_backup.tar 100% 62GB 111.5MB/s 09:26 scp: /root/gitlabDataBackup/1513967001_2017_12_23_9.4.3_gitlab_backup.tar: No space left on deviceroot@ubuntu4146:/data/gitlabData/backups#
通过日志可以看得出来,在scp过程中,远程的备份服务器已经没有剩余空间可以使用。
我们来查看下 远程服务器的 剩余空间,如下所示:
[root@localhost gitlabDataBackup]# df -h Filesystem Size Used Avail Use% Mounted on/dev/sda3 454G 454G 0 100% /tmpfs 3.9G 72K 3.9G 1% /dev/shm/dev/sda1 20G 81M 19G 1% /boot[root@localhost gitlabDataBackup]#
因此,这几次有时候失败的原因就是因为远程服务器没有剩余空间可用了。然而我们的script命令需要改进下,因为不管 scp 命令执行如何,我们的script命令都是执行成功的,因此下面的if判断逻辑是有问题的,会一直给我们发送备份成功的邮件!尴尬!
因此我们需要修改该脚本,将该脚本拆分成两个脚本,一个还是原来的 scp 备份文件到远程备份服务的脚本
auto_backup_to_remote.sh*,另外一个是script命令原来记录scp执行过程的脚本auto_backup_to_remote_script.sh*
auto_backup_to_remote.sh* 源代码
#!/bin/bash# gitlab 机房备份路径LocalBackDir=/data/gitlabData/backups# 远程备份服务器(FTP服务器) gitlab备份文件存放路径RemoteBackDir=/data/gitlabDataBackup# 远程备份服务器 登录账户RemoteUser=root# 远程机房代码备份服务器IP地址RemoteIP1=远程服务器IP地址#当前系统日期DATE=`date +"%Y-%m-%d"`#Log存放路径LogFile=$LocalBackDir/log/$DATE.log#邮件写入的文件mailcontent=$LocalBackDir/mail/mailcontent_$DATEmailToUser=ouyangpeng的邮箱mailToUser1=领导1的邮箱mailToUser2=领导2的邮箱#新建日志文件touch $LogFile#追加日志到日志文件echo "Gitlab auto backup to remote server, start at $(date +"%Y-%m-%d %H:%M:%S")" > $LogFileecho "---------------------------------------------------------------------------" >> $LogFile# 查找 本地备份目录下 时间为180分钟之内的,并且后缀为.tar的gitlab备份文件BACKUPFILE_SEND_TO_REMOTE=$(find /data/gitlabData/backups -type f -mmin -180 -name '*.tar*')# 输出日志,打印出每次scp的文件名echo "---------------------The file to scp to remote server is: $BACKUPFILE_SEND_TO_REMOTE-------------------------------" >> $LogFile#备份到 远程机房代码备份服务器scp -v $BACKUPFILE_SEND_TO_REMOTE $RemoteUser@$RemoteIP1:$RemoteBackDir# $?符号显示上一条命令的返回值,如果为0则代表执行成功,其他表示失败if [ $? -eq 0 ];then #追加日志到日志文件 echo "-----------------------------------Success!----------------------------------------" >> $LogFile echo "Gitlab auto backup to remote server, end at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile #写Email的正文内容 > "$mailcontent" echo "GitLab Backup Daily Report, backup to remote server Success ! Please Check your Email and read the following log file" >> $mailcontent #读取mailcontent内容当做邮件正文 ,附件为Log文件 #cat $mailcontent | mail -s "Congratulation! GitLab backup to remote server Success Report." -t $mailToUser $mailToUser1 $mailToUser2 -A $LogFile #成功的话,只发送给我一个人即可,不需要发送给其他人 cat $mailcontent | mail -s "Congratulation! GitLab backup to remote server Success Report." $mailToUser -A $LogFileelse #追加日志到日志文件 echo "-----------------------------------Failed!---------------------------------------" >> $LogFile echo "Gitlab auto backup to remote server failed at $(date +"%Y-%m-%d %H:%M:%S")" >> $LogFile #写Email的正文内容 > "$mailcontent" echo "GitLab Backup Daily Report,Backup to remote server Failed ! Please Check your Email and read the following log file !" >> $mailcontent #读取mailcontent内容当做邮件正文 ,附件为Log文件 cat $mailcontent | mail -s "Warning! GitLab Backup to remote server Failed Report." -t $mailToUser $mailToUser1 $mailToUser2 -A $LogFilefi
auto_backup_to_remote_script.sh*文件源代码是
#!/bin/bash# gitlab 机房备份路径LocalBackDir=/data/gitlabData/backups#当前系统日期DATE=`date +"%Y-%m-%d"`#Log存放路径LogFile=$LocalBackDir/log/$DATE.log#Script命令记录的存放路径和文件名ScriptLogFile=$LocalBackDir/script_log/$DATE.logScriptTimeFile=$LocalBackDir/script_log/$DATE.date#新建日志文件touch $ScriptLogFiletouch $ScriptTimeFile#开始启动script记录整个过程,执行 /data/gitlabData/backups/auto_backup_to_remote.sh 脚本script -a $ScriptLogFile -c"/data/gitlabData/backups/auto_backup_to_remote.sh"
这样就可以了,然后将原来的定时任务执行的脚本文件修改下即可。
vi /etc/crontab
修改定时定时任务执行的脚本文件为 /data/gitlabData/backups/auto_backup_to_remote_script.sh
# edited by ouyang 2017-8-17 添加定时任务,每天凌晨三点,执行gitlab备份到远程服务器0 4 * * * root /data/gitlabData/backups/auto_backup_to_remote_script.sh
编写完 /etc/crontab 文件之后,需要重新启动cron服务
#重新加载cron配置文件sudo /usr/sbin/service cron reload#重启cron服务sudo /usr/sbin/service cron restart
ok,这样就修改好了。
五、参考链接
- https://linux.cn/article-3195-1.html
- http://blog.jobbole.com/70563/
- http://blog.csdn.net/u011497904/article/details/45418505
- http://blog.csdn.net/u011192270/article/details/46462651
- https://www.cnblogs.com/cornell/p/3833955.html
- http://bbs.chinaunix.net/thread-4103971-1-1.html
- http://blog.csdn.net/reyleon/article/details/13999033
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/78818492
本文同步发表在阿里云栖:https://yq.aliyun.com/articles/292313如果觉得本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行随意打赏。您的支持将鼓励我继续创作!