技术栈

主页 > 移动开发 >

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

技术栈 - 中国领先的IT技术门户

一、背景

在之前的博客 【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-1602:00:02
---------------------------------------------------------------------------
-----------------------------------Success!----------------------------------------
Gitlab auto backup at local server, end at  2017-12-1602:29:35
root@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命令的用法

[email protected]:/# script --help

Usage:
 script [options] [file]

Options:
 -a, --append            append the output
 -c, --command <command> run command rather than interactive shell
 -r, --returnreturn 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

[email protected]:/# 

这里写图片描述

2.2.1 [file]选项

  • 1、当file为空时,操作内容将记录到当前目录中名称为typescript的文本文件中。

例如,我们直接输入script,不加file选项的时候,开始记录终端的操作行为,并将操作内容输出到当前目录的typescript中,如下图所示:

root@ubuntu4146:/# scriptScript started, file is typescript
root@ubuntu4146:/# 

这里写图片描述

生成的默认文件为 typescript ,如下图所示:

这里写图片描述

  • 2、如果指定file,那么将把终端的操作内容记录到file文件中。
[email protected]:/# exitexit

Script done on20171216日 星期六 112406[email protected]:/# script script_ouyangpeng.his
Script started, fileis script_ouyangpeng.his
[email protected]:/# ll
total 660
drwxr-xr-x  26 root root   4096121611:25 ./
drwxr-xr-x  26 root root   4096121611:25 ../
drwxr-xr-x   2 root root   4096121516:23 bin/
drwxr-xr-x   3 root root   40961132015 boot/
drwxr-xr-x   3 root root   409612102015 build/
drwxr-xr-x   8 root root   409681711:38 data/
drwxr-xr-x  15 root root   420012509:54 dev/
drwxr-xr-x 130 root root  12288121516:24 etc/
drwxr-xr-x   4 root root   409611202016 home/
lrwxrwxrwx   1 root root     331132015 initrd.img -> boot/initrd.img-3.19.0-25-generic
drwxr-xr-x  22 root root   4096132017 lib/
drwxr-xr-x   2 root root  12288132017 lib32/
drwxr-xr-x   2 root root   4096132017 lib64/
drwxr-xr-x   2 root root   4096132017 libx32/
drwx------   2 root root  16384 11月  3  2015 lost+found/
drwxr-xr-x   3 root root   40961132015 media/
drwxr-xr-x   2 root root   40964112014 mnt/
drwxr-xr-x   4 root root   409681011:06 opt/
dr-xr-xr-x 461 root root      012509:54 proc/
drwx------   8 root root   4096 12月 16 10:00 root/
drwxr-xr-x  24 root root    840121611:26run/
drwxr-xr-x   2 root root   4096121516:23 sbin/
-rw-r--r--   1 root root      0 12月 16 11:25 script_ouyangpeng.his
drwxr-xr-x   3 root root   409611162016 srv/
dr-xr-xr-x  13 root root      0121611:21 sys/
drwxrwxrwt   8 root root 552960121611:25 tmp/
-rw-r--r--   1 root root   2217 12月 16 11:24 typescript
drwxr-xr-x  15 root root   40961142015 usr/
drwxr-xr-x  14 root root   40962242017 var/
lrwxrwxrwx   1 root root     301132015 vmlinuz -> boot/vmlinuz-3.19.0-25-generic
[email protected]:/# 

这里写图片描述

如上代码所示,我们先exit掉第一个script命令,然后我们开始第二个script命令,并且直接file选项为 script_ouyangpeng.his。这样就会在当前目录下生成一个script_ouyangpeng.his文件。

2.2.2 [options]选项

[email protected]:/data/gitlabData/backups# script --help

Usage:
 script [options] [file]

Options:
 -a, --append            append the output
 -c, --command <command> run command rather than interactive shell
 -r, --returnreturn 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可选项。

先从简单的来

root@ubuntu4146:/# script -V
script from util-linux 2.20.1

这里写图片描述

[email protected]:/# script -h

Usage:
 script [options] [file]

Options:
 -a, --append            append the output
 -c, --command <command> run command rather than interactive shell
 -r, --returnreturn 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

[email protected]:/# 

这里写图片描述

root@ubuntu4146:/# scriptScript started, file is typescript
root@ubuntu4146:/# exit
exit
Script done, file is typescript
root@ubuntu4146:/# script -q
root@ubuntu4146:/# exit
exit
root@ubuntu4146:/# 

这里写图片描述

我们先使用 script script_ouyangpeng.his 命令来记录,然后敲一个echo "Hello OuyangPeng"来输出一句话,接着使用exit命令退出script记录。

root@ubuntu4146:/# script script_ouyangpeng.his Script started, file is script_ouyangpeng.his
root@ubuntu4146:/# echo "Hello OuyangPeng"HelloOuyangPeng
root@ubuntu4146:/# exit
exit
Script done, file is script_ouyangpeng.his

这里写图片描述

现在我们可以查看下 script_ouyangpeng.his 文件中的内容

root@ubuntu4146:/# script script_ouyangpeng.his Script started, file is script_ouyangpeng.his
root@ubuntu4146:/# echo "Hello OuyangPeng"HelloOuyangPeng
root@ubuntu4146:/# exit
exit
Script done, file is script_ouyangpeng.his
root@ubuntu4146:/# vim script_ouyangpeng.his 
root@ubuntu4146:/# more script_ouyangpeng.his Script started on 20171216日 星期六 114713秒
root@ubuntu4146:/# echo "Hello OuyangPeng"HelloOuyangPeng
root@ubuntu4146:/# exit
exit

Script done on 20171216日 星期六 114737秒
root@ubuntu4146:/# 

这里写图片描述

如上图所示,记录文件中的内容完完全全将我们的所有操作都记录下来了。

现在我们使用 script -a 选项 在 script_ouyangpeng.his 记录文件上追加内容,如下所示:

root@ubuntu4146:/# script -a script_ouyangpeng.his Script started, file is script_ouyangpeng.his
root@ubuntu4146:/# echo "Hello OuyangPeng , using the option -a "HelloOuyangPeng , using the option -a 
root@ubuntu4146:/# exit
exit
Script done, file is script_ouyangpeng.his
root@ubuntu4146:/# 

这里写图片描述

命令执行完之后,我们来查看下 script_ouyangpeng.his 文件内容

这里写图片描述

root@ubuntu4146:/# script -t 2>script_ouyangpeng.time -a script_ouyangpeng.his Script started, file is script_ouyangpeng.his
root@ubuntu4146:/# echo "hello script -t "
hello script -t 
root@ubuntu4146:/# exit
exit
Script done, file is script_ouyangpeng.his
root@ubuntu4146:/# 

这里写图片描述

选项-t用于存储时序文件,这里导入到stderr,再重定向到script_ouyangpeng.time,
选项-a用于将命令输出信息,追加到script_ouyangpeng.his文件。

这样录制视屏就很方便啦,而且这两个文件很小,可以拷贝到需要播放的机器上进行播放。

script_ouyangpeng.time文件内容如下

root@ubuntu4146:/# cat script_ouyangpeng.time 0.687691420.011893 14.88278710.23982310.14395810.14401210.17583910.89622110.10491010.43116031.08029930.087901 30.13644730.13580430.17670330.13522830.31229130.19981430.19220330.15179630.35200630.19211136.89696930.97597430.17602030.34409438.946105620.41501213.22420610.26411410.12896510.3914748

这里写图片描述

script_ouyangpeng.his文件如下

[email protected]:/# cat script_ouyangpeng.his 
Script started on20171216日 星期六 114713[email protected]:/# echo "Hello OuyangPeng"
Hello OuyangPeng
[email protected]:/# exitexit

Script done on20171216日 星期六 114737秒
Script started on20171216日 星期六 115345[email protected]:/# echo "Hello OuyangPeng , using the option -a "
Hello OuyangPeng , using the option -a 
[email protected]:/# exitexit

Script done on20171216日 星期六 115429秒
Script started on20171216日 星期六 120535[email protected]:/# echo "hello script -t "
hello script -t 
[email protected]:/# exitexit

Script done on20171216日 星期六 120607[email protected]:/# 

这里写图片描述

在第一个命令框输入

root@ubuntu4146:/# script -f  -t 2>script_ouyangpeng_f.time -a script_ouyangpeng_f.his Script started, file is script_ouyangpeng_f.his
root@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图片了。

[email protected]:/# script -a "script_ouyangpeng_c.his" -c "ls -h"
Script started, file is script_ouyangpeng_c.his
bin    dev     lib     lost+found  proc  script_ouyangpeng_c.his   script_ouyangpeng.time  usr
boot   etc     lib32   media       root  script_ouyangpeng_f.his   srv             var
build  home    lib64   mnt         run   script_ouyangpeng_f.time  sys             vmlinuz
data   initrd.img  libx32  opt         sbin  script_ouyangpeng.his     tmp
Script done, file is script_ouyangpeng_c.his
[email protected]:/# 

这里写图片描述

-c 后面,接上命令 ls -h ,然后将记录追加到script_ouyangpeng_c.his文件中

现在我们来查看 script_ouyangpeng_c.his文件

[email protected]:/# cat script_ouyangpeng_c.his 
Script started on20171216日 星期六 124916秒
bin    dev     lib     lost+found  proc  script_ouyangpeng_c.his   script_ouyangpeng.time  usr
boot   etc     lib32   media       root  script_ouyangpeng_f.his   srv             var
build  home    lib64   mnt         run   script_ouyangpeng_f.time  sys             vmlinuz
data   initrd.img  libx32  opt         sbin  script_ouyangpeng.his     tmp

Script done on20171216日 星期六 124916[email protected]:/# 

这里写图片描述

2.2.3 退出script

要退出记录活动,我们可以在终端中按下Ctrl+D,或者输入exit。在退出script前,你会发现记录文件的大小为0 Kb,而在退出之后,文件大小会发生改变。

这里写图片描述

[email protected]:/#script-a"script_ouyangpeng_exit.his"Scriptstarted,fileisscript_ouyangpeng_exit.his[email protected]:/#lltotal680drwxr-xr-x26rootroot409612月1612:53./drwxr-xr-x26rootroot409612月1612:53../drwxr-xr-x2rootroot409612月1516:23bin/drwxr-xr-x3rootroot409611月32015boot/drwxr-xr-x3rootroot409612月102015build/drwxr-xr-x8rootroot40968月1711:38data/drwxr-xr-x15rootroot420012月509:54dev/drwxr-xr-x130rootroot1228812月1516:24etc/drwxr-xr-x4rootroot409611月202016home/lrwxrwxrwx1rootroot3311月32015initrd.img-> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x22rootroot40961月32017lib/drwxr-xr-x2rootroot122881月32017lib32/drwxr-xr-x2rootroot40961月32017lib64/drwxr-xr-x2rootroot40961月32017libx32/drwx------2rootroot1638411月32015lost+found/drwxr-xr-x3rootroot409611月32015media/drwxr-xr-x2rootroot40964月112014mnt/drwxr-xr-x4rootroot40968月1011:06opt/dr-xr-xr-x464rootroot012月509:54proc/drwx------8rootroot409612月1611:47root/drwxr-xr-x24rootroot84012月1612:53run/drwxr-xr-x2rootroot409612月1516:23sbin/-rw-r--r--1rootroot46112月1612:49script_ouyangpeng_c.his-rw-r--r--1rootroot012月1612:53script_ouyangpeng_exit.his-rw-r--r--1rootroot17612月1612:47script_ouyangpeng_f.his-rw-r--r--1rootroot146012月1612:47script_ouyangpeng_f.time-rw-r--r--1rootroot431212月1612:36script_ouyangpeng.his-rw-r--r--1rootroot55512月1612:36script_ouyangpeng.timedrwxr-xr-x3rootroot409611月162016srv/dr-xr-xr-x13rootroot012月1611:21sys/drwxrwxrwt8rootroot55296012月1612:50tmp/drwxr-xr-x15rootroot409611月42015usr/drwxr-xr-x14rootroot40962月242017var/

在执行命令之后,还是 0 字节

[email protected]:/#echo"helloscriptexit"helloscriptexit[email protected]:/#lltotal680drwxr-xr-x26rootroot409612月1612:53./drwxr-xr-x26rootroot409612月1612:53../drwxr-xr-x2rootroot409612月1516:23bin/drwxr-xr-x3rootroot409611月32015boot/drwxr-xr-x3rootroot409612月102015build/drwxr-xr-x8rootroot40968月1711:38data/drwxr-xr-x15rootroot420012月509:54dev/drwxr-xr-x130rootroot1228812月1516:24etc/drwxr-xr-x4rootroot409611月202016home/lrwxrwxrwx1rootroot3311月32015initrd.img-> boot/initrd.img-3.19.0-25-genericdrwxr-xr-x22rootroot40961月32017lib/drwxr-xr-x2rootroot122881月32017lib32/drwxr-xr-x2rootroot40961月32017lib64/drwxr-xr-x2rootroot40961月32017libx32/drwx------2rootroot1638411月32015lost+found/drwxr-xr-x3rootroot409611月32015media/drwxr-xr-x2rootroot40964月112014mnt/drwxr-xr-x4rootroot40968月1011:06opt/dr-xr-xr-x458rootroot012月509:54proc/drwx------8rootroot409612月1611:47root/drwxr-xr-x24rootroot84012月1612:53run/drwxr-xr-x2rootroot409612月1516:23sbin/-rw-r--r--1rootroot46112月1612:49script_ouyangpeng_c.his-rw-r--r--1rootroot012月1612:53script_ouyangpeng_exit.his-rw-r--r--1rootroot17612月1612:47script_ouyangpeng_f.his-rw-r--r--1rootroot146012月1612:47script_ouyangpeng_f.time-rw-r--r--1rootroot431212月1612:36script_ouyangpeng.his-rw-r--r--1rootroot55512月1612:36script_ouyangpeng.timedrwxr-xr-x3rootroot409611月162016srv/dr-xr-xr-x13rootroot012月1611:21sys/drwxrwxrwt8rootroot55296012月1612:50tmp/drwxr-xr-x15rootroot409611月42015usr/drwxr-xr-x14rootroot40962月242017var/lrwxrwxrwx1rootroot3011月32015vmlinuz-> boot/vmlinuz-3.19.0-25-generic[email protected]:/#

这里写图片描述

这个时候,我们输入 exit 之后,再去查看文件大小

[email protected]:/# exitexit
Script done, fileis script_ouyangpeng_exit.his
[email protected]:/# ll
total 688
drwxr-xr-x  26 root root   4096121612:53 ./
drwxr-xr-x  26 root root   4096121612:53 ../
drwxr-xr-x   2 root root   4096121516:23 bin/
drwxr-xr-x   3 root root   40961132015 boot/
drwxr-xr-x   3 root root   409612102015 build/
drwxr-xr-x   8 root root   409681711:38 data/
drwxr-xr-x  15 root root   420012509:54 dev/
drwxr-xr-x 130 root root  12288121516:24 etc/
drwxr-xr-x   4 root root   409611202016 home/
lrwxrwxrwx   1 root root     331132015 initrd.img -> boot/initrd.img-3.19.0-25-generic
drwxr-xr-x  22 root root   4096132017 lib/
drwxr-xr-x   2 root root  12288132017 lib32/
drwxr-xr-x   2 root root   4096132017 lib64/
drwxr-xr-x   2 root root   4096132017 libx32/
drwx------   2 root root  16384 11月  3  2015 lost+found/
drwxr-xr-x   3 root root   40961132015 media/
drwxr-xr-x   2 root root   40964112014 mnt/
drwxr-xr-x   4 root root   409681011:06 opt/
dr-xr-xr-x 465 root root      012509:54 proc/
drwx------   8 root root   4096 12月 16 11:47 root/
drwxr-xr-x  24 root root    840121612:55run/
drwxr-xr-x   2 root root   4096121516: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.time
drwxr-xr-x   3 root root   409611162016 srv/
dr-xr-xr-x  13 root root      0121611:21 sys/
drwxrwxrwt   8 root root 552960121612:50 tmp/
drwxr-xr-x  15 root root   40961142015 usr/
drwxr-xr-x  14 root root   40962242017 var/
lrwxrwxrwx   1 root root     301132015 vmlinuz -> boot/vmlinuz-3.19.0-25-generic
[email protected]:/# 

这里写图片描述

至此,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  [email protected]:/root/gitlabDataBackup"

这个命令的意思,使用 script 命令记录我们的 scp命令执行的结果,执行记录文件保存在 /data/gitlabData/backups/script_log/scp_2017-12-16.log 文件中。

整个执行过程如下所示:

[email protected]:/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  [email protected]:/root/gitlabDataBackup"
Script started, file is /data/gitlabData/backups/script_log/scp_2017-12-16.log
Executing: program /usr/bin/ssh host 172.xxx.xxx.xxx, user root, commandscp -v -t /root/gitlabDataBackup
OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line19: Applying options for *
debug1: Connecting to172.xxx.xxx.xxx [172.xxx.xxx.xxx] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type 1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: identity file /root/.ssh/id_ed25519 type -1
debug1: identity file /root/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local versionstring SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8
debug1: Remote protocol version2.0, remote software version OpenSSH_5.3
debug1: match: OpenSSH_5.3 pat OpenSSH_5* compat 0x0c000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<3072<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: RSA c8:d1:29:e8:ec:62:0c:6e:57:d5:3f:8a:25:cc:01:9c
debug1: Host '172.xxx.xxx.xxx' is known and matches the RSA host key.
debug1: Found key in /root/.ssh/known_hosts:5
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available

debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available

debug1: Unspecified GSS failure.  Minor code may provide more information


debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available

debug1: Next authentication method: publickey
debug1: Offering RSA public key: /root/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug1: key_parse_private2: missing begin marker
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
Authenticated to172.xxx.xxx.xxx ([172.xxx.xxx.xxx]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = zh_CN.UTF-8
debug1: Sending command: scp -v -t /root/gitlabDataBackup
Sending file modes: C0600 653843353601513362071_2017_12_16_9.4.3_gitlab_backup.tar
Sink: C0600 653843353601513362071_2017_12_16_9.4.3_gitlab_backup.tar
1513362071_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 ondevice
debug1: channel 0: free: client-session, nchannels 1
Script done, file is /data/gitlabData/backups/script_log/scp_2017-12-16.log
[email protected]:/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_$DATE

mailToUser=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 [email protected]$RemoteIP2:$RemoteBackDir#备份到 远程机房代码备份服务器
scp $BACKUPFILE_SEND_TO_REMOTE$RemoteUser@$RemoteIP1:$RemoteBackDir# $?符号显示上一条命令的返回值,如果为0则代表执行成功,其他表示失败if [ $? -eq0 ];then#追加日志到日志文件echo"-----------------------------------Success!----------------------------------------" >> $LogFileecho"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!---------------------------------------" >> $LogFileecho"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_$DATE

mailToUser=ouyangpeng的邮箱
mailToUser1=领导1的邮箱
mailToUser2=领导2的邮箱

#新建日志文件
touch $LogFile
touch $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 [email protected]$RemoteIP2:$RemoteBackDir#备份到 远程机房代码备份服务器#scp $BACKUPFILE_SEND_TO_REMOTE [email protected]$RemoteIP1:$RemoteBackDir
script -qa $ScriptLogFile -c" scp -v $BACKUPFILE_SEND_TO_REMOTE$RemoteUser@$RemoteIP1:$RemoteBackDir"# $?符号显示上一条命令的返回值,如果为0则代表执行成功,其他表示失败if [ $? -eq0 ];then#追加日志到日志文件echo"-----------------------------------Success!----------------------------------------" >> $LogFileecho"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!---------------------------------------" >> $LogFileecho"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 [email protected]$RemoteIP1:$RemoteBackDir
script -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.tar88%   54GB 111.5MB/s   01:07 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar89%   55GB 111.6MB/s   00:57 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar91%   56GB 111.7MB/s   00:48 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar93%   57GB 111.8MB/s   00:38 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar94%   58GB 111.6MB/s   00:29 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar96%   59GB 111.8MB/s   00:19 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar98%   60GB 111.8MB/s   00:10 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar99%   62GB 111.9MB/s   00:00 ETA
1513967001_2017_12_23_9.4.3_gitlab_backup.tar100%   62GB 111.5MB/s   09:26scp: /root/gitlabDataBackup/1513967001_2017_12_23_9.4.3_gitlab_backup.tar: No space left on device
[email protected]:/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_$DATE

mailToUser=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 [ $? -eq0 ];then#追加日志到日志文件echo"-----------------------------------Success!----------------------------------------" >> $LogFileecho"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!---------------------------------------" >> $LogFileecho"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.log
ScriptTimeFile=$LocalBackDir/script_log/$DATE.date

#新建日志文件
touch $ScriptLogFile
touch $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备份到远程服务器04    * * *   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

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

这里写图片描述

责任编辑:admin  二维码分享:
本文标签:
点击我更换图片

评论列表