资讯动态

Linux日志保存与录屏实操:重定向、nohup到asciinema完整指南

发布时间:2026/10/22 6:18:13 来源:尧图企业网站定制
1. 日志和录屏为什么值得放在一起说我见过不少同事排查问题靠眼睛盯着终端看完就忘出了问题又要从头查一遍跑个脚本服务输出刷过去就没了等程序崩了才发现日志什么都没留下写了一个复杂命令操作过程很关键想发给同事看结果只能靠截图一张一张贴拼起来别人也看不懂前后顺序。这三个场景看起来是不同的问题本质却完全一致都没有把当时发生了什么可靠地保存下来。日志文件保存和屏幕录制一个是把程序的输出持久化一个是把人的操作过程持久化。一个适合事后查证据一个适合事后看演示。但很多Linux用户的习惯是——日志只用复制粘贴录屏全靠手机拍屏幕。说实话这两种做法既不专业也不稳定更不方便检索。这篇内容我不打算讲特别高深的理论而是把我自己在日常运维、脚本开发、给别人做演示时实际用到、实测过的一套方法整理出来怎么用重定向、nohup、tee把日志稳稳落盘怎么用script和scriptreplay录制终端会话怎么用asciinema录可分享的终端动画以及怎么用ffmpeg录整个桌面。适合刚接触Linux、但已经开始被日志缺失和演示麻烦折磨的开发者也适合想把整套保存流程系统化梳理一遍的运维同学。2. 先把最基本的日志落盘姿势吃透2.1 重定向组合 21为什么必须把标准错误也带上先说最常用的把命令输出保存到文件。ls file_list.txt这条命令大多数人会用但只做到了标准输出重定向。问题在于如果ls遇到权限不足它不会把错误信息写到标准输出而是写到标准错误用上面的命令你会发现自己得到一个空文件然后满屏都是报错。正确的写法是ls file_list.txt 21这个组合里21的意思是把标准错误也重定向到标准输出当前指向的地方。很多新手不理解为什么不是21而是21——因为不加的话21会被解析成创建一个名字叫1的文件加了才表示指向标准输出这个文件描述符。这个细节我至少看人踩过三次坑。再进阶一步如果你希望把正常信息和错误信息分开存command out.log 2 err.log这在跑批量任务时非常有用。比如处理一批文件正常处理的结果放一个文件失败的部分放另一个文件后面只盯err.log就能知道哪些需要重新处理。2.2 追加而不是覆盖用 保住历史痕迹是覆盖写是追加写。这个区别在测试脚本时特别容易出问题。我见过有人循环跑测试每次都执行script.sh result.log结果跑完发现result.log里只有最后一次循环的输出之前的全被覆盖了。按理说一次脚本执行用没问题但如果是一个会执行多轮、或者需要累积日志的服务就一定要用。举一个实际场景。我在某台服务器上定时跑数据同步任务每天凌晨执行一次任务本身就写了一个日志0 2 * * * /opt/sync/run.sh /var/log/sync_task.log 21任务执行完想看历史记录直接cat /var/log/sync_task.log从第一天到昨天的记录全在。如果用第二天就只剩当天的内容前面发生过的所有事情全部丢失。叠加已经在极端场景下做过备份恢复这种只有最后一次结果的日志基本帮不上任何忙。2.3 想边看边存tee 是重定向的完美补充有时候你希望输出既在屏幕上滚动又要存进文件里。重定向做不到这一点但tee可以command | tee log.txttee这个名字来自管道分叉的形态——像字母T一头接进来两头分出去一头给屏幕一头给文件。加-a参数就是追加模式command | tee -a log.txt我在写部署脚本时几乎每步都会加tee比如./configure 21 | tee -a build.log make 21 | tee -a build.log这样如果你在终端实时观察编译进度编译完文件里也有一份完整记录。后面真有哪一步失败翻日志就能看到是在configure阶段挂的还是在make阶段挂的不用重跑一遍。3. 跑后台任务时日志怎么处理才不丢不乱3.1 nohup 的定位让进程在会话结束后继续跑前面说的重定向都是前台运行CtrlC中断后进程结束日志随之停止。如果你要让程序在SSH断开后继续运行就得配合nohup使用。nohup python3 train_model.py train.log 21 这个命令的含义是忽略挂断信号hangup signal把输出写进train.log在后台运行。SSH断开、终端关闭这个进程不会收到SIGHUP会继续正常执行。注意命令结尾的它把进程放到后台。如果你忘了写这个整个命令会占据当前终端你只能另开一个终端去干别的事。nohup这种方式的一个坑是进程确实在跑但是它的标准输入已经不再连接到终端。有些程序运行过程中会尝试读取输入遇到这种情况就会挂住或者直接报错。所以用nohup之前最好确认你要跑的程序在非交互式环境下能正常工作。3.2 实践组合nohup 21我自己在服务器上跑长任务用的标准组合是nohup bash /opt/scripts/pipeline.sh /var/log/pipeline_$(date %Y%m%d).log 21 这里做了三件事用nohup让它不随会话退出被杀用按天追加日志避免覆盖用21把错误输出也收进来。文件名加了日期变量这样每天的日志独立成文件后面要查某一天的问题直接按文件名定位就行。跑起来后怎么确认它在正常运行最直接的方式是tail -f /var/log/pipeline_xxx.logtail -f会持续输出文件新增内容一旦看到新的日志行说明进程还在工作。想看进程本身的状态配合ps -ef | grep pipeline以及top里看CPU和内存占用基本能判断有没有假死。还有一个细节nohup命令返回的PID也可以用echo $!获取。在脚本里如果需要管理多个后台任务把PID存下来后面要杀进程或者检查状态都方便。nohup ./long_task.sh task.log 21 echo $! task.pid3.3 避免日志文件把自己磁盘撑爆日志一直追加会有另一个后果磁盘满了。尤其是那种每秒钟都写几行日志的程序几天不管一个几十GB的文件就出来了。我在测试环境里见过一台机器就因为日志把/dev/vda1占满整个服务全挂排查了半天才发现只是磁盘写满了。解决思路是配合logrotate做轮转。Linux自带的logrotate通过配置来决定何时切割、压缩、删除旧日志。简单配置一个放在/etc/logrotate.d/下面/var/log/pipeline.log { daily rotate 7 compress delaycompress missingok notifempty }这段配置的意思是每天轮转一次保留最近7份旧日志压缩成.gz压缩动作推迟一天执行因为刚轮转的日志可能还有进程在写日志不存在时跳过日志为空时不轮转。配置完成后可以手动试一下logrotate -vf /etc/logrotate.d/pipeline-v打印详细过程-f强制执行一次轮转。看到输出确认切割生效再交给cron定时执行。我个人的习惯是所有自己维护的日志文件只要可能持续增长都必须配logrotate。不配的日志本质上就是一个定时炸弹你永远不知道它哪一天会把磁盘塞满。4. systemd时代怎么把丢了的日志捞回来如果你用的是有systemd的发行版现在主流的基本都是还有一个经常被忽略的日志来源journald。4.1 journalctl 基础用法不用落盘也有日志systemd管理的服务标准输出默认会交给journald也就是日志会被自动收集到journal里。你不需要自己写重定向只要服务是通过systemd启动的事后都能查journalctl -u my-service.service-u指定单元名。加上--since和--until可以限定时间范围journalctl -u my-service.service --since 2025-01-01 10:00:00 --until 2025-01-01 12:00:00这样连服务什么时候启动、什么时候退出、中间打了什么日志全部能看到。有个细节值得注意日志持久化。把/etc/systemd/journald.conf里的Storage改成persistent日志就会写到/var/log/journal/重启后历史日志也不会丢。默认情况下如果没设置可能用的是内存tmpfs重启后之前日志就全没了。4.2 想让journal长期落盘一个配置改掉编辑/etc/systemd/journald.conf[Journal] Storagepersistent SystemMaxUse500MSystemMaxUse500M限制日志占用的最大磁盘空间超过之后会自动清理最旧的日志。改完配置重启服务systemctl restart systemd-journald这个方案比前文手动重定向更省心服务本身不用改日志自动收、自动轮转、自动限制大小。但并不是说有了journald前文的重定向、nohup就完全没用。对于自己跑的、不通过systemd管理的脚本和命令它们不会进入journal必须手动重定向。两条路线各有适用场景搭配起来才完整。我自己是通过systemd跑的服务交给journald收集前台临时跑的任务用重定向tee长期后台任务用nohuplogrotate。5. 终端会话录制script 和 scriptreplay说完了日志下面这部分讲的保存人做了什么。你手动敲了哪些命令、命令输出什么这个过程同样可以被完整记录下来。5.1 script一条命令录制你的会话过程Linux自带的script命令就是一个终端会话录制器。用法极其简单script /tmp/session.log执行之后终端里显示的几乎所有内容都会被记录到session.log里包括你敲的命令、命令输出、终端控制字符等。操作完退出录制输入exit即可。script有一个非常重要的参数--timing它可以记录每个输出发生的时间点script --timingtiming.txt /tmp/session.log这个timing文件后续用来做回放的时间同步。没有它你只能看到静止的文本有了它整个操作过程才能像视频一样按时间节奏重现。5.2 scriptreplay按时间节奏回放整个操作回放命令是scriptreplay --timingtiming.txt /tmp/session.log执行之后终端会按照当时操作的速度一行一行重现一遍连命令之间的停顿都会保留。这个功能在做远程排障、复盘别人怎么定位问题的时候尤其好用。我有一次帮同事排查故障他做了十几步操作光靠聊天软件里的截图根本讲不清楚让他录了一个会话文件发过来用scriptreplay一看整个定位过程一目了然。如果嫌回放速度太慢想加速scriptreplay --timingtiming.txt --divisor2 /tmp/session.log--divisor2表示用1/2的时间播完也就是加速一倍。数值越大加速越多想看细节可以减速--divisor0.5比原始速度慢一倍。顺带说一句很多人不知道script还能配合管道使用在自动化脚本的最外层包一层script --timingautotext_timing.txt autotext_session.log -c ./deploy.sh-c执行完指定命令后自动退出录制。这样批量部署的过程不用人工干预就能留下完整会话记录和节奏时间后续复盘或出问题时很管用。6. ASCII动画录制把终端操作变成一段可嵌入的视频script录制的文件是纯文本回放依赖本地的scriptreplay。如果你想分享给远程的人或者直接放到博客、文档里给别人观看asciinema是更好的选择。6.1 asciinema 的基本用法asciinema录制的是终端字符流生成的文件是一种轻量的ASCII动画不是视频文件体积小而且可以在网页里直接播放、复制选择文本。安装方式各发行版不太一样但包名基本都是asciinema通过系统包管理器安装即可# Debian/Ubuntu系 apt install asciinema # RHEL/CentOS系 dnf install asciinema录制asciinema rec demo.cast操作完按CtrlD或输入exit结束它会提示是否上传到asciinema官网按提示选择即可。如果不希望上传录完直接生成了本地.cast文件。6.2 本地回放与嵌入页面回放本地文件asciinema play demo.cast网页里播放的话比如在个人博客里可以用asciinema的player组件或者干脆把.cast文件放到任何支持它的平台上。asciinema最大卖点之一是字符版视频可以像文本一样直接复制读者选中哪一段复制出来的就是真实的命令和输出。我自己写技术文档时如果需要演示某个交互流程优先用asciinema而不是桌面录屏。因为ASCII动画体积小、加载快、可复制、看起来干净。Ffmpeg录出来的视频动辄几十MB放进去读者加载也慢。需要注意的一点asciinema录制的是终端内容不是整个屏幕。如果操作涉及图形界面比如浏览器调试、画图工具asciinema完全无能为力下面接下来要说的桌面录屏才是正确姿势。7. 桌面录屏ffmpeg 与内置工具的三种路线如果要保存的是整个桌面、程序窗口或者图形界面的操作可靠的方案有好几种。我按使用成本排一下。7.1 最简单GNOME内置录屏GNOME桌面环境自带录屏功能快捷键是CtrlAltShiftR。按下去开始录制右上角出现一个红点再按一次停止视频会保存到~/Videos/目录。这个方案我不太用体验上有点太基础了不能选区域、不能选帧率。但它毕竟一条命令都不用敲对临时录一段非常有用。你需要的只是GNOME桌面而不是额外装任何工具。7.2 命令行全能选手ffmpeg如果你习惯命令行ffmpeg是录制桌面最灵活的方式。它能选区域、选音频源、选编码参数完全可控。录整个屏幕默认分辨率ffmpeg -f x11grab -i :0 -c:v libx264 -crf 23 out.mp4其中-f x11grab指定使用X11抓屏协议:0指定显示器编号在单显示器的机器上基本就是它。-c:v libx264指定编码器-crf 23是质量参数数值越小质量越高23是比较均衡的默认值。录指定区域需要知道坐标和尺寸语法如下ffmpeg -f x11grab -video_size 1280x720 -i :0.0100,50 -c:v libx264 out.mp4-video_size 1280x720是录制区域的宽高100,50是区域左上角在屏幕上的坐标。如果需要同时录音加上音频设备参数ffmpeg -f x11grab -i :0 -f pulse -i default -c:v libx264 -c:a aac out.mp4不过我一般建议新手先别急着加音频等视频能正常录了再逐步加。一次把参数全加上出了问题反而难定位比如视频有画面没声音你根本不确定是音频设备选错还是脉冲音频服务没起来。7.3 后台录屏和定时录屏桌面录屏还有一个常被忽视的需要无人值守或者后台开启录制。比如你要录一个长时间运行的演示不想一直盯着ffmpeg的进程看可以放到后台nohup ffmpeg -f x11grab -video_size 1920x1080 -i :0 -c:v libx264 -crf 20 record_$(date %s).mp4 2/dev/null 结合前文日志的知识可以把ffmpeg的状态日志也保存下来用前文方法统一管理。如果你想录一段固定时长的视频加-t参数单位是秒ffmpeg -f x11grab -i :0 -t 60 out.mp4这条命令会在60秒后自动停止正好可以用来做定时片段录制。FFmpeg黑屏坑建议有些环境卡在x11grab无法打开DISPLAY通常是SSH登录的会话没有X权限。解决办法是在本地图形会话里执行或者用export DISPLAY:0指定显示编号。这个坑我踩过所以补充一说。8. 实操中总结的几条经验这部分不算教程但比教程更值得记。都是我从日常操作里踩出来的。第一所有的日志数据都比想象中更重要。一次运行没有记录日志下次出问题复盘时你会发现只能靠猜。宁可多写一行日志也不要让一条日志白白刷过去。哪怕是临时测试的脚本也值得用tee分一份出来。第二重定向前先想清楚要不要追加。我自己吃过亏统计脚本用覆盖写结果跑了三天的数据最后只留下最后一天的。后面凡是可能反复执行的命令我默认都写除非能明确确认这个文件就是只留最新内容。第三录制和回放是两个动作别混为一谈。录的时候注意保存timing文件没有timingscript和asciinema回放就失去节奏感只剩一堆文字。asciinema如果只想本地录制记得关掉上传选项或者录完选不上传否则终端输出的内容可能被存到第三方平台。第四桌面录屏优先考虑码率和文件体积。默认的encoder未必适合长视频。我自己固定用libx264crf值控制质量crf从18到28之间调试。对普通操作演示来说crf26或27就足够清晰了体积小传给别人也容易。如果你想对压缩时间敏感比如录宣讲可以用-preset ultrafast但要注意文件会比默认大很多。第五日志轮转这步别省。用journald的SystemMaxUse限制大小用手动脚本的话配合logrotate总之让日志有一个可自清理的上限。磁盘被日志写满是所有不看日志的服务器最容易碰到的问题没有之一。我现在习惯是凡是要花超过五分钟跑的操作从头录一份asciinema或script凡是超过一天持续运行的任务日志一定配上轮转和独立目录。刚开始觉得多此一举直到有一次一个月前的生产故障靠一份当时随手录的终端会话复盘出了根本原因我才真正体会到保存记录这件事怎么重视都不为过。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑