首页 >工作总结 > 内容

【Linux学习 】Linux使用Script命令来记录并回放终端会话

2023年9月22日 00:21

一、背景

在之前的博客 【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 20171216日 星期六 112406秒root@ubuntu4146:/# script script_ouyangpeng.hisScript started, file is script_ouyangpeng.hisroot@ubuntu4146:/# lltotal 660drwxr-xr-x  26 root root   4096 1216 11:25 ./drwxr-xr-x  26 root root   4096 1216 11:25 ../drwxr-xr-x   2 root root   4096 1215 16:23 bin/drwxr-xr-x   3 root root   4096 113  2015 boot/drwxr-xr-x   3 root root   4096 1210  2015 build/drwxr-xr-x   8 root root   4096  817 11:38 data/drwxr-xr-x  15 root root   4200 125 09:54 dev/drwxr-xr-x 130 root root  12288 1215 16:24 etc/drwxr-xr-x   4 root root   4096 1120  2016 home/lrwxrwxrwx   1 root root     33 113  2015 initrd.img -> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x  22 root root   4096  13  2017 lib/drwxr-xr-x   2 root root  12288  13  2017 lib32/drwxr-xr-x   2 root root   4096  13  2017 lib64/drwxr-xr-x   2 root root   4096  13  2017 libx32/drwx------   2 root root  16384 11月  3  2015 lost+found/drwxr-xr-x   3 root root   4096 113  2015 media/drwxr-xr-x   2 root root   4096  411  2014 mnt/drwxr-xr-x   4 root root   4096  810 11:06 opt/dr-xr-xr-x 461 root root      0 125 09:54 proc/drwx------   8 root root   4096 12月 16 10:00 root/drwxr-xr-x  24 root root    840 1216 11:26 run/drwxr-xr-x   2 root root   4096 1215 16:23 sbin/-rw-r--r--   1 root root      0 12月 16 11:25 script_ouyangpeng.hisdrwxr-xr-x   3 root root   4096 1116  2016 srv/dr-xr-xr-x  13 root root      0 1216 11:21 sys/drwxrwxrwt   8 root root 552960 1216 11:25 tmp/-rw-r--r--   1 root root   2217 12月 16 11:24 typescriptdrwxr-xr-x  15 root root   4096 114  2015 usr/drwxr-xr-x  14 root root   4096  224  2017 var/lrwxrwxrwx   1 root root     30 113  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 20171216日 星期六 114713秒root@ubuntu4146:/# echo "Hello OuyangPeng"Hello OuyangPengroot@ubuntu4146:/# exitexitScript done on 20171216日 星期六 114737秒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 20171216日 星期六 114713秒root@ubuntu4146:/# echo "Hello OuyangPeng"Hello OuyangPengroot@ubuntu4146:/# exitexitScript done on 20171216日 星期六 114737秒Script started on 20171216日 星期六 115345秒root@ubuntu4146:/# echo "Hello OuyangPeng , using the option -a "Hello OuyangPeng , using the option -a root@ubuntu4146:/# exitexitScript done on 20171216日 星期六 115429秒Script started on 20171216日 星期六 120535秒root@ubuntu4146:/# echo "hello script -t "hello script -t root@ubuntu4146:/# exitexitScript done on 20171216日 星期六 120607秒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 20171216日 星期六 124916秒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 20171216日 星期六 124916秒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 1216 12:53 ./drwxr-xr-x  26 root root   4096 1216 12:53 ../drwxr-xr-x   2 root root   4096 1215 16:23 bin/drwxr-xr-x   3 root root   4096 113  2015 boot/drwxr-xr-x   3 root root   4096 1210  2015 build/drwxr-xr-x   8 root root   4096  817 11:38 data/drwxr-xr-x  15 root root   4200 125 09:54 dev/drwxr-xr-x 130 root root  12288 1215 16:24 etc/drwxr-xr-x   4 root root   4096 1120  2016 home/lrwxrwxrwx   1 root root     33 113  2015 initrd.img -> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x  22 root root   4096  13  2017 lib/drwxr-xr-x   2 root root  12288  13  2017 lib32/drwxr-xr-x   2 root root   4096  13  2017 lib64/drwxr-xr-x   2 root root   4096  13  2017 libx32/drwx------   2 root root  16384 11月  3  2015 lost+found/drwxr-xr-x   3 root root   4096 113  2015 media/drwxr-xr-x   2 root root   4096  411  2014 mnt/drwxr-xr-x   4 root root   4096  810 11:06 opt/dr-xr-xr-x 465 root root      0 125 09:54 proc/drwx------   8 root root   4096 12月 16 11:47 root/drwxr-xr-x  24 root root    840 1216 12:55 run/drwxr-xr-x   2 root root   4096 1215 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 1116  2016 srv/dr-xr-xr-x  13 root root      0 1216 11:21 sys/drwxrwxrwt   8 root root 552960 1216 12:50 tmp/drwxr-xr-x  15 root root   4096 114  2015 usr/drwxr-xr-x  14 root root   4096  224  2017 var/lrwxrwxrwx   1 root root     30 113  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 20171223日 星期六 040002

这里写图片描述

查看日志最后

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,这样就修改好了。


五、参考链接


这里写图片描述

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/78818492
本文同步发表在阿里云栖:https://yq.aliyun.com/articles/292313

如果觉得本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行随意打赏。您的支持将鼓励我继续创作!

这里写图片描述


参考文章:https://blog.csdn.net/ouyang_peng/article/details/78818492

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时候联系我们修改或删除,在此表示感谢。

特别提醒:

1、请用户自行保存原始数据,为确保安全网站使用完即被永久销毁,如何人将无法再次获取。

2、如果上次文件较大或者涉及到复杂运算的数据,可能需要一定的时间,请耐心等待一会。

3、请按照用户协议文明上网,如果发现用户存在恶意行为,包括但不限于发布不合适言论妄图

     获取用户隐私信息等行为,网站将根据掌握的情况对用户进行限制部分行为、永久封号等处罚。

4、如果文件下载失败可能是弹出窗口被浏览器拦截,点击允许弹出即可,一般在网址栏位置设置

5、欢迎将网站推荐给其他人,网站持续更新更多功能敬请期待,收藏网站高效办公不迷路。

      



登录后回复

共有0条评论