2. Linux终端录屏和回放
cript命令简介 当你在终端或控制台上工作时,你可能想记录下自己做了些什么。这种记录可以看成是保存了终端痕迹的文档。假设你跟一些Linux管理员同时在系统上干活。或者说你让别人远程到你的服务器。你就会想记录下终端发生过什么。要实现它,你可以使用script命令。
2.1 什么script命令¶
script 是一个神奇命令,可以使用script工具记录用户在当前终端的所有的操作,已经输出到屏幕的内容。将这些信息保存到指定的文本文件中。 也就是说,script命令在你需要记录或者存档终端活动时可能很有用,记录文件会存储为文本文件,所以可以很方便地用文本编辑器打开。 在使用script命令将终端的会话过程录制下来之后,可以使用 scriptreplay将其录制的结果播放给他人观看。 script 的好处就在于你在终端中的所有操作、敲过的命令和打印出的结果它都可以原原本本地进行录制。可以应用于教学、演示、审计。
2.2 script命令操作¶
使用 script --help 命令来查看 script命令的用法
leco@leco:~$ script --help Usage: script [options] [file] Make a typescript of a terminal session. 选项: -a, --append append the output -c, --command <command> run command rather than interactive shell -e, --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 For more details see script(1). 解释 -a选项 在现有输出录制的文件的内容上追加新的内容 -c选项 后面可以加上需要执行的命令,而不是交互式shell上执行的命令 -r选项 子进程中返回退出代码 -f选项 如果需要在输出到日志文件的同时,也可以查看日志文件的内容,可以使用 -f 参数。PS:可以用于教学,两个命令行接-f可以实时演示 -q选项 可以使script命令以静默模式运行 -t选项 指明输出录制的时间数据 -V选项 输出script的版本信息,然后退出 -h选项 输出script的help信息,然后退出
-
[file] 选项
-
1、当file为空时,操作内容将记录到当前目录中名称为typescript的文本文件中。
root@leco:~/summer# ls # 之前是没有文件的 root@leco:~/summer# script # 启动,默认保存是typescript文件 脚本已启动,文件为 typescript root@leco:~/summer# exit #退出 exit 脚本完成,文件为 typescript root@leco:~/summer# ls typescript 查看内容 root@leco:~/summer# cat typescript 脚本启动于 2019年01月23日 星期三 09时56分56秒 root@leco:~/summer# exit exit 脚本完成,于 2019年01月23日 星期三 09时57分03秒
-
2、如果指定file,那么将把终端的操作内容记录到file文件中。
root@leco:~/summer# rm typescript # 删除之前做实验的默认输出文件 root@leco:~/summer# ls root@leco:~/summer# script summerout.log # 指定输出文件 脚本已启动,文件为 summerout.log root@leco:~/summer# ls # 开始操作 summerout.log root@leco:~/summer# echo 'my love from summer' my love from summer root@leco:~/summer# exit # 退出 exit 脚本完成,文件为 summerout.log root@leco:~/summer# ls # 显示记录的指定文件内容 summerout.log root@leco:~/summer# cat summerout.log # 查看记录的内容,以下是记保存了 操作历史 脚本启动于 2019年01月23日 星期三 09时59分02秒 root@leco:~/summer# ls summerout.log root@leco:~/summer# echo 'my love from summer' my love from summer root@leco:~/summer# exit exit 脚本完成,于 2019年01月23日 星期三 09时59分25秒
-
- 查看版本
root@leco:~/summer# script -V script,来自 util-linux 2.27.1
- script -q 选项 静默输出
#1. 不带-q的操作 root@leco:~/summer# ls root@leco:~/summer# script 脚本已启动,文件为 typescript # 此时会提示这个。带-q就不输出 root@leco:~/summer# ls typescript root@leco:~/summer# echo 'hello' hello root@leco:~/summer# exit exit 脚本完成,文件为 typescript #2. 带-q的操作 root@leco:~/summer# ls typescript root@leco:~/summer# rm typescript root@leco:~/summer# ls root@leco:~/summer# script -q root@leco:~/summer# echo 'hello' hello root@leco:~/summer# exit exit root@leco:~/summer# ls typescript
- script -a 选项
-a选项 在现有输出录制的文件的内容上追加新的内容
root@leco:~/summer# ls typescript root@leco:~/summer# rm typescript # 删除之前操作历史 root@leco:~/summer# ls root@leco:~/summer# script # 开始记录 脚本已启动,文件为 typescript root@leco:~/summer# echo '123' 123 root@leco:~/summer# echo '345' 345 root@leco:~/summer# exit # 退出 exit 脚本完成,文件为 typescript root@leco:~/summer# ls typescript root@leco:~/summer# cat typescript # 查看操作历史 脚本启动于 2019年01月23日 星期三 10时07分56秒 root@leco:~/summer# echo '123' 123 root@leco:~/summer# echo '345' 345 root@leco:~/summer# exit exit 脚本完成,于 2019年01月23日 星期三 10时08分08秒 # 以上都是第一次操作的历史‘ root@leco:~/summer# script -a # 开始第二次,也就是-a 就是追加内容到第一次操作文件中 脚本已启动,文件为 typescript root@leco:~/summer# echo '第二次操作123' 第二次操作123 root@leco:~/summer# echo '第二次操作456' 第二次操作456 root@leco:~/summer# exit exit 脚本完成,文件为 typescript root@leco:~/summer# ls typescript root@leco:~/summer# cat typescript 脚本启动于 2019年01月23日 星期三 10时07分56秒 root@leco:~/summer# echo '123' 123 root@leco:~/summer# echo '345' 345 root@leco:~/summer# exit exit 脚本完成,于 2019年01月23日 星期三 10时08分08秒 脚本启动于 2019年01月23日 星期三 10时08分20秒 root@leco:~/summer# echo '第二次操作123' 第二次操作123 root@leco:~/summer# echo '第二次操作456' 第二次操作456 root@leco:~/summer# exit exit 脚本完成,于 2019年01月23日 星期三 10时08分35秒
- script -t 选项
-t选项 指明输出录制的时间数据
root@leco:~/summer# ls root@leco:~/summer# script -t 2>datas.time -aq commands.his root@leco:~/summer# echo '123' 123 root@leco:~/summer# echo '456' 456 root@leco:~/summer# exit exit root@leco:~/summer# ls commands.his datas.time root@leco:~/summer# cat commands.his 脚本启动于 2019年01月23日 星期三 10时16分38秒 root@leco:~/summer# echo '123' 123 root@leco:~/summer# echo '456' 456 root@leco:~/summer# exit exit root@leco:~/summer# cat datas.time 0.016874 44 1.117511 4 0.213036 12 0.189993 8 0.639560 2 0.000082 5 0.000225 44 0.316049 10 0.155868 16 0.388290 12 0.719740 2 0.000032 5 0.000301 44 1.598040 1 0.222087 1 0.368449 1 0.256182 1 0.269758 2 0.000071 6 root@leco:~/summer#
选项-t用于存储时序文件,这里导入到stderr,再重定向到datas.time, 选项-a用于将命令输出信息,追加到commands.his文件。 这样录制视屏就很方便啦,而且这两个文件很小,可以拷贝到需要播放的机器上进行播放。
# 回放命令,接下来后面就像放电影一样,重复你之前操作,自己操作一波,体会效果 root@leco:~/summer# scriptreplay datas.time commands.his root@leco:~/summer# echo '123' 123 root@leco:~/summer# echo '456' 456 root@leco:~/summer# exit exit
scriptreplay 后面数据文件,后命令文件
- script -f 选项
-f选项 如果需要在输出到日志文件的同时,也可以查看日志文件的内容,可以使用 -f 参数。PS:可以用于教学,两个命令行接-f可以实时演示
root@leco:~/summer# ls root@leco:~/summer# script -t 2>datas.time -a commands.his 脚本已启动,文件为 commands.his root@leco:~/summer# echo '开始教学了' 开始教学了 root@leco:~/summer# script -f 脚本已启动,文件为 typescript root@leco:~/summer# echo '你在认真看吗' 你在认真看吗
- script -c 选项
-c选项 后面可以加上需要执行的命令,而不是交互式shell上执行的命令
root@leco:~/summer# script -a "commands.his" -c "ifconfig|grep 192.168.5.110" 脚本已启动,文件为 commands.his inet 地址:192.168.5.110 广播:192.168.5.255 掩码:255.255.255.0 脚本完成,文件为 commands.his root@leco:~/summer# exit exit root@leco:~/summer# ls commands.his root@leco:~/summer# cat commands.his 脚本启动于 2019年01月23日 星期三 10时34分58秒 inet 地址:192.168.5.110 广播:192.168.5.255 掩码:255.255.255.0 脚本完成,于 2019年01月23日 星期三 10时34分58秒
2.3 退出script¶
要退出记录活动,我们可以在终端中按下Ctrl+D,或者输入exit。在退出script前,你会发现记录文件的大小为0 Kb,而在退出之后,文件大小会发生改变。
记录历史的文件在执行过程中都是0字节,退出的时候才写入该文件。
root@leco:~/summer# script exit.his 脚本已启动,文件为 exit.his root@leco:~/summer# ls exit.his root@leco:~/summer# echo '123' 123 root@leco:~/summer# du -sh exit.his 0 exit.his root@leco:~/summer# echo '12312' 12312 root@leco:~/summer# du -sh exit.his 0 exit.his root@leco:~/summer# exit exit 脚本完成,文件为 exit.his root@leco:~/summer# du -sh exit.his 4.0K exit.his root@leco:~/summer# cat exit.his 脚本启动于 2019年01月23日 星期三 10时37分44秒 root@leco:~/summer# ls exit.his root@leco:~/summer# echo '123' 123 root@leco:~/summer# du -sh exit.his 0 exit.his root@leco:~/summer# echo '12312' 12312 root@leco:~/summer# du -sh exit.his 0 exit.his root@leco:~/summer# exit exit 脚本完成,于 2019年01月23日 星期三 10时38分05秒
三、Script命令结合实际使用场景¶
3.1 案例1 定时备份¶
先在终端执行script命令记录scp命令过程,先在终端敲个命令
script datas.his -c 'sh for.sh'
root@leco:~/summer# ls for.sh root@leco:~/summer# cat for.sh for((i=0;i<10;i++)) do echo $i done root@leco:~/summer# script datas.his -c 'sh for.sh' 脚本已启动,文件为 datas.his 0 1 2 3 4 5 6 7 8 9 脚本完成,文件为 datas.his root@leco:~/summer# ls datas.his for.sh root@leco:~/summer# cat datas.his # 查看历史记录 脚本启动于 2019年01月23日 星期三 10时41分52秒 0 1 2 3 4 5 6 7 8 9 脚本完成,于 2019年01月23日 星期三 10时41分52秒
script记录整个过程结束。 从结果来看,整个过程使用script命令记录是没有问题的
看下以下实例 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")" > $LogFile echo "---------------------------------------------------------------------------" >> $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 $LogFile else #追加日志到日志文件 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 $LogFile fi
#!/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"
# edited by summer 2019-01-23 添加定时任务,每天凌晨1点,执行gitlab备份到远程服务器 0 1 * * * /bin/bash /scripts/gitlab/auto_backup_to_remote_script.sh
3.2 案例2 服务器安全审计¶
直接操作线上的服务器有很大隐患,所以一般都是通过登录跳板机,然后连接线上服务器,跳板机可以访问控制和安全审计,查看记录每个人对线上服务器的操作 用户家目录下,修改环境变量,使得用户登录就会触发录像
root@leco:/datas/commands# tail -1 /etc/profile script -t -f -q 2>/datas/commands/$USER-$UID-`date +%Y%m%d%H%M%S`.time -a /datas/commands/$USER-$UID-`date +%Y%m%d%H%M%S`.his root@leco:/datas/commands# chmod 777 /datas/commands/ root@leco:/datas/commands# ls root@leco:/datas/commands# 此时还没有日志,接下来,重新登录用户
新开一个终端 *** 需要重启系统 *** Last login: Wed Jan 23 11:03:09 2019 from 192.168.5.1 leco@leco:~$ ip a|grep 192.168.5. inet 192.168.5.110/24 brd 192.168.5.255 scope global enp3s0 leco@leco:~$ echo 'hello' hello
leco@leco:~$ root@leco:/datas/commands# ls leco-1000-20190123110350.his leco-1000-20190123110350.time # 1. 单独查看 命令历史 root@leco:/datas/commands# cat leco-1000-20190123110350.his 脚本启动于 2019年01月23日 星期三 11时03分50秒 leco@leco:~$ ip a|grep 192.168.5. inet 192.168.5.110/24 brd 192.168.5.255 scope global enp3s0 leco@leco:~$ echo 'hello' hello # 查看动态历史 root@leco:/datas/commands# scriptreplay leco-1000-20190123110350.time leco-1000-20190123110350.his leco@leco:~$ ip a|grep 192.168.5. inet 192.168.5.110/24 brd 192.168.5.255 scope global enp3s0 leco@leco:~$ echo 'hello' hello leco@leco:~$ 自己操作,查看效果
这样搞完后,发现有一个问题是每次退出,我习惯Ctrl+D,然后按第一遍停止录像,第二遍才能用户退出,如何解决在后面添加
if [ "$SHLVL" = 1 ]; then exit fi
root@leco:/datas/commands# tail -4 /etc/profile script -t -f -q 2>/datas/commands/$USER-$UID-`date +%Y%m%d%H%M%S`.time -a /datas/commands/$USER-$UID-`date +%Y%m%d%H%M%S`.his if [ "$SHLVL" = 1 ]; then exit fi
区别
SHLVL 这个变量是干什么的?
shell中的$SHLVL
,记录当前shell的嵌套层次,初始为1
比如下面的例子:当前是在第1层,执行bash命令之后,$SHLVL
变量变为2
root@leco:/datas/commands# echo $SHLVL 1 root@leco:/datas/commands# bash root@leco:/datas/commands# echo $SHLVL 2 root@leco:/datas/commands# exit exit root@leco:/datas/commands# echo $SHLVL 1
SHLVL 和 BASH_SUBSHELL 两个变量的区别