1. 日志保存的基本思路与工具选型
先聊一个实际场景。你在终端里跑了一个耗时半小时的脚本,人离开了一会儿,回来发现屏幕被输出刷爆了,关键报错早就滚出了缓冲区。往上翻?终端最多保存几千行,后面的内容全被冲掉了。这时候你才想起来,刚才就该把输出存成文件。类似的事我遇到不下十次,所以后来干脆养成习惯:不管跑什么命令,只要有长输出,一律留日志。
日志保存的核心就一句话——把标准输出和标准错误分流管理。不光是“存下来”,还要能区分正常信息和报错信息,要能看到时间戳,要能控制文件大小,要让旧日志自动清理。这些需求看起来琐碎,但组合起来就是一个完整的日志方案。实际工作中,根据场景不同,我会用几套不同的工具组合:
| 工具/命令 | 核心能力 | 适用场景 | 学习成本 |
|---|---|---|---|
tee | 同时输出到屏幕和文件 | 临时保存单次命令输出 | 极低 |
script | 记录整个终端会话,包括交互过程 | 操作留痕、教学演示 | 低 |
nohup+& | 后台运行并保存输出 | 跑长任务 | 低 |
logrotate | 日志轮转、压缩、过期清理 | 长期运行的服务日志 | 中 |
rsyslog | 集中式日志管理 | 多机多应用统一收拢 | 高 |
你别一上来就上 rsyslog 那套重的,很多场景根本用不上。我更推荐按需选择,先从简单的tee和script用起来,等真的需要长期维护了,再引入 logrotate 做自动化。
1.1 为什么不能只靠重定向符
很多人说,日志不就是command > file.log 2>&1吗?对,这能存,但有一个明显短板——你完全看不到底盘发生了什么。命令卡住了、进度条不动了、运行到哪一步了,你全都不知道,只能干等或者另开终端去tail -f。而如果用tee,屏幕和文件同时有输出,既能看到实时状态,又能留下完整存档,这就是我优先推荐它的原因。
另外还有个细节,>重定向会把文件覆盖掉,跑第二次就把第一次的记录冲没了。要是想追加,得用>>。很多人刚用的时候在这个上面踩过坑,辛辛苦苦跑了一晚上,第二次跑了个小测试,日志文件直接清空重来。要避免这个问题,一是记住>>追加,二是干脆给日志文件名加上时间戳。比如:
command > log_$(date +%Y%m%d_%H%M%S).log 2>&1这样每个文件独立存在,不会互相覆盖,找历史记录也方便。
1.2 日志里到底该存什么
刚接触日志管理的时候,我习惯把所有输出一股脑全存下来,觉得越全越好。后来发现问题了:日志文件动辄几百 MB,真要排查问题时,全靠grep去捞,效率极低。正确的思路是分层记录——程序自己的日志只记 ERROR 和 WARN,调试信息单独一个文件,运行状态概要又一个文件。这样排查时先看概要,再定位错误,最后翻调试细节,路径清晰很多。
如果你写的是自己的脚本,建议从一开始就规范输出格式。统一用[时间] [级别] 消息这个模板,比如:
log_info() { echo "[$(date '+%F %T')] [INFO] $*"; } log_error() { echo "[$(date '+%F %T')] [ERROR] $*" >&2; }这样一来,grep ERROR和grep INFO各取所需,排查问题的效率能翻好几倍。我见过不少项目,日志一大堆,就是没用标准格式,排查全靠人肉看。这习惯一定要早改。
2. 实操:tee、script、screen 组合拳
讲完了思路,下面进入实际操作环节。这套组合覆盖了绝大部分日常需求:单命令输出、完整会话记录、长任务后台运行。
2.1 tee:最基础也最实用的命令
tee的用法一句话说明:把标准输入同时写到标准输出和一个或多个文件。管道配合使用时尤其好用:
ping -c 10 某服务器 | tee ping_test.log这个命令在屏幕显示 ping 结果的同时,把内容完整写进了文件。想追加而不是覆盖,加-a参数:
ping -c 10 某服务器 | tee -a ping_test.log如果你还需要把标准错误也存下来,配合2>&1:
make build 2>&1 | tee build.log这里有个小坑,如果你用的是较新版本的 bash,直接跑command 2>&1 | tee file会有一个副作用——整条管道里$?取到的是tee的退出码,而不是你那个命令的退出码。判断命令失败得用${PIPESTATUS[0]}:
make build 2>&1 | tee build.log exit_code=${PIPESTATUS[0]}这是一个老手都容易忽略的细节,排查自动化脚本的时候特别容易在这里翻车。
2.2 script:录制整个终端会话
tee有个局限——它只能记录命令的输出,如果你在终端里用 vim 编辑文件、跑 htop 看进程、跟数据库交互,这些有交互界面的操作,tee就记不全了。这时候该用script。
script会把整个终端会话的原始输入输出都录下来,包括那些交互界面的控制序列。最常用的用法:
script -a session_$(date +%F).log输入这个命令后会进入一个新的 shell 子进程,你接下来的所有操作都会被记录。退出用exit或者按Ctrl+D。加-a表示追加,不覆盖之前的记录。
查看录制的文件时,直接用cat会因为控制字符而乱成一团,建议这样:
cat session_20240115.log或者干脆把script和scriptreplay配合使用,实现完整回放。先录制带时间戳的文件:
script -t 2> timing.log -a session.log然后回放:
scriptreplay timing.log session.log回放的时候连命令输入的速度、停顿的时长都能还原,非常像观看一段录像。用于重现一个复杂的部署操作过程、给团队做操作复盘,效果极佳。不过要注意,scriptreplay依赖终端尺寸一致,换个窗口大小回放,就可能错位。解决方法是录制时固定终端尺寸,或者回放前用resize -s调整到相同行列数。
2.3 screen / tmux:长任务的绝配
tee和script适合“事后存档”,但如果你要跑一个需要几十小时的编译任务、数据导入任务,终端窗口又不能关,那就得靠终端复用器——screen或者tmux。我的习惯是tmux配合tee双保险:
tmux new -s longtask ./long_task.sh 2>&1 | tee long_task.log这样即使 SSH 断开,任务也继续在 tmux 会话里跑,日志同时被tee保存。过一会儿重新 SSH 进来:
tmux attach -t longtask就能重新看到任务界面。日志也完整保存在long_task.log里,两头都不耽误。
如果你用的系统上没装 tmux,多半也有screen,功能类似:
screen -S longtask ./long_task.sh > long_task.log 2>&1然后Ctrl + A再按D脱离会话,重新连接用screen -r longtask。注意,脱离之后没人接管终端,日志只能靠重定向保存,这里的tee就不起作用了。
2.4 手动日志归档小技巧
日志保存的实操里,还有一个很实用的习惯:给日志文件加时间前缀,按天归档。比如写个简单脚本,配合 cron 在凌晨执行:
#!/bin/bash # 将昨天的日志压缩归档 cd /var/log/myapp find . -name "*.log" -mtime +1 -exec gzip {} \;更进一步,可以用logrotate配置系统的轮转策略。日志轮转是个大话题,但入门只需要理解三个参数就行:
/var/log/myapp/*.log { daily # 按天轮转 rotate 7 # 保留最近 7 份 compress # 压缩旧日志 missingok # 日志不存在不报错 }配置好之后,旧日志不会无限堆积,磁盘也不会被撑爆。别小看这点,很多服务器挂掉的原因不是程序崩了,而是/var分区被日志占满,导致各种进程写不了文件直接宕机。
3. 屏幕录制的常用工具与实战对比
日志解决的是“文本输出留痕”,但有些场景光有文字远远不够。比如你给别人演示一个 GUI 软件的操作步骤,或者向团队展示某个 bug 复现过程,视频录制更直观。Linux 下屏幕录制工具不少,我结合实际使用体验给你捋一捋。
3.1 主流录制工具横向对比
| 工具 | 安装方式 | 支持平台 | 录制质量 | 操作复杂度 | 适合场景 |
|---|---|---|---|---|---|
ffmpeg | 包管理器 | 命令行,可脚本化 | 极高,可选任意编码/帧率 | 中 | 自动化录制、批量处理 |
obs-studio | 包管理器 | GUI,界面操作 | 高,支持多场景切换 | 低 | 直播、教学、多源混流 |
peek | 包管理器 | GUI,极简 | 中,GIF/MP4 | 极低 | 快速录个短视频、GIF |
kazam | 包管理器 | GUI,简洁 | 中 | 低 | 日常录屏、录音 |
gnome-screenshot | 系统自带 | GUI/CLI | 低,只能截图 | 极低 | 偶尔截个图 |
如果你只录一次操作过程,用peek十几秒就能搞定,选择区域、点录制、结束保存,完事。但你要是想集成到自动化脚本里,或者有精准的编码参数需求,那还是ffmpeg更值得花时间学。
3.2 ffmpeg 命令行录屏入门
ffmpeg功能极其强大,但录屏只是它的一小部分功能。在 Linux 上,录屏通常走 X11 协议,基本命令长这样:
ffmpeg -f x11grab -video_size 1920x1080 -framerate 30 -i :0.0 -c:v libx264 -preset ultrafast output.mp4参数拆解一下:-f x11grab指定输入格式是 X11 抓屏;-video_size是录制分辨率;-framerate控制帧率;-i :0.0表示抓取显示器 0 的屏幕;-c:v libx264选用 H.264 编码;-preset ultrafast是为了降低 CPU 占用。录制中按q结束。
只录某个窗口区域的话,可以先查窗口位置:
xwininfo点击目标窗口后会输出绝对坐标和尺寸,再把这些参数喂给ffmpeg:
ffmpeg -f x11grab -video_size 1280x720 -framerate 30 -i :0.0+200,100 -c:v libx264 output.mp4+200,100是录制的起始坐标。这一招特别适合只录软件主界面,不把旁边的浏览器窗口、聊天窗口录进去,避免隐私泄露,也让视频更聚焦。
如果要同时录麦克风声音,加一行音频输入:
ffmpeg -f x11grab -video_size 1920x1080 -framerate 30 -i :0.0 -f pulse -i default -c:v libx264 -preset ultrafast -c:a aac output.mp4这已经是比较完整的录屏命令了。注意-preset ultrafast会让生成的文件偏大,但是录制过程中 CPU 消耗低,不容易导致系统卡顿。如果机器性能好、视频要长期保存,可以换成-preset medium,压缩率更高、文件更小,代价是多花点编码时间。
3.3 OBS Studio 的进阶用法
ffmpeg胜在灵活,但要在录制过程中动态切换窗口、叠加摄像头画面、调音量,那就得靠obs-studio了。OBS 的全称是 Open Broadcaster Software,别看它界面稍复杂,一旦配置好,体验远超命令行。
OBS 的核心概念是“场景+源”。“场景”是最终输出画面的一个完整组合,“源”是画面里的每个元素。录屏时,大多数人这么配:
- 新建一个“场景”,命名“软件操作演示”。
- 添加“显示器采集”源,选主显示器。
- 添加“窗口采集”源,选你录制的软件窗口。
- 添加“音频输入采集”,选你的麦克风。
- 点右侧“开始录制”。
为什么推荐用“窗口采集”而不是“显示器采集”?因为窗口采集会始终聚焦在那个软件上,哪怕你中途切换到别的窗口,输出画面还是你选的软件,观众不会看到你切来切去的过程。显示器采集则是全屏幕照单全收,包括你临时弹出的浏览器、手机通知,全都暴露在视频里。虽然两者都能用,但大多数演示场景,窗口采集更专业。
OBS 里面有个细节,设置里记得把“录像格式”设为 MKV 而不是 MP4。原因是如果在录制过程中 OBS 崩溃或者你强制关机,MP4 文件基本报废,MKV 还能完整保留。录完之后,再用 OBS 自带的“重新封装”功能一键转成 MP4,这样既保证了可靠性,又方便播放。
3.4 录制结束后的轻量剪辑
录完的视频往往需要裁剪头尾、把中间等待的部分剪掉。很多人一上来就装所谓“专业剪辑软件”,其实完全没必要。ffmpeg两行命令就能搞定基础的片段截取和拼接。
截取从第 10 秒到第 30 秒的片段:
ffmpeg -ss 10 -t 20 -i input.mp4 -c copy output_cut.mp4命令里的-ss 10表示从第 10 秒开始,-t 20表示持续 20 秒。加-c copy意味着不重新编码,只做快速切割,几秒钟就能完成。不过这种方式切出来的时间点不一定精确按关键帧对齐,可能会有半秒偏差。对日常用途来说无伤大雅,真要精确到每一帧,就得移除-c copy重新编码,代价是耗时变长。
多个片段合并,先把要合并的文件写进列表:
echo "file 'part1.mp4'" > list.txt echo "file 'part2.mp4'" >> list.txt echo "file 'part3.mp4'" >> list.txt ffmpeg -f concat -safe 0 -i list.txt -c copy merged.mp4同样用-c copy,不做重编码,秒合。注意片段之间编码参数要一致,不要一段是 30 帧、一段是 60 帧,否则合成时播放会出现卡顿或音画不同步。
4. 日志与录制结合的场景实践
到这里,日志保存和屏幕录制各自的操作都讲完了,但你别把它们当成两个孤立功能。实际工作中,这两者经常要配合使用,才能达到完整的“操作留痕”效果。
4.1 故障排查场景:全方位还原现场
我记得有一次模拟生产环境压测时出现性能抖动,当时我跑了压测脚本,同时做了一份终端会话录制:
script -t 2> timing.log -a perf_test.log python3 run_load_test.py 2>&1 | tee -a perf_test.log事后复盘时,文本日志帮我定位到具体哪个时间点出现大量超时,timing.log+scriptreplay回放又让我看到当时屏幕上打印出的详细错误字,还原了整个现场。这种“文本主线+视频旁证”的组合,比单纯看日志文件直观得多。
更妙的是,你还可以在录屏的同时让时间戳滚起来。用 OBS 加一个“文本源”,显示date命令的输出并定时刷新,录出来的视频每一帧都有当前时间,对排查问题和培训演示都极其有帮助。不过这需要在录制环境里装一个时钟 widget,或者用 OBS 的文本源+定时脚本实现,稍微折腾一点,但效果值回票价。
4.2 教学演示场景:录一遍抵十次口头描述
Linux 小白学命令行时,最头痛的是“你描述的界面我没见过”。与其在聊天里反复打字,不如直接录一段 30 秒视频发过去。先用ffmpeg或peek录下操作过程,再配一两句文字说明,对方照着做一遍就会了。这个技巧对新同事尤其友好,因为新人对终端快捷键、编辑器操作普遍不熟,视频能传递大量“隐含操作”——比如你按了什么组合键、鼠标拖动了哪个区域、菜单点了哪一项,这些在纯文本日志里根本体现不出来。
另外,录屏时如果配了麦克风讲解,我建议先用ffmpeg -f pulse -i default小音量录一条测试,确认一下麦克风电平。很多入门者录完了一看视频才发现——声音没有、声音太小、或者录进了风扇噪音。测试不花时间,后面的返工才费时间。
4.3 自动化任务:定时录屏+日志存档两不误
除了手动操作,Linux 还能把录屏和日志保存编排成自动化任务。比如你想记录每天早晨系统启动后前 5 分钟的桌面操作,或者定期把某块屏幕的操作过程存档。用 cron 加一段脚本就能搞定。
脚本内容大致如下:
#!/bin/bash # 自动录屏 300 秒并记录系统状态日志 LOGDIR=~/screen_logs/$(date +%F) mkdir -p "$LOGDIR" vmstat 1 300 > "$LOGDIR/system_load.log" & ffmpeg -f x11grab -video_size 1920x1080 -framerate 15 -i :0.0 \ -t 300 -c:v libx264 -preset ultrafast "$LOGDIR/screen.mp4" wait echo "[$(date '+%F %T')] Capture done." >> "$LOGDIR/archive.log"把这段脚本放进 cron,比如每天早上 09:00 自动跑:
0 9 * * * /home/user/bin/capture_morning.sh这样既不打扰你干活,又能形成完整的历史记录。回看某天系统卡顿的现场、磁盘 IO 飙升时对应的屏幕操作,会非常痛快。
5. 常见问题与排查技巧实录
这部分整理的,全是我自己实际用的时候踩过的坑和解决的问题。每个都对应一条实用的避坑技巧,建议你收藏备用。
5.1 录制的视频文件太大怎么办
录屏视频动辄几个 GB?很多人第一反应是提高压缩率,其实先看看帧率和分辨率是不是设置过高了。桌面操作根本不需 60 帧,25-30 帧完全够用。分辨率方面,如果你只需要展示代码,1080p 已经是天花板了,但很多人误选“显示器原始分辨率”,4K 录出来,文件体积直接爆炸,观众还得放大才能看清,体验反而不如直接 1080p。
ffmpeg压文件有两个关键参数:
ffmpeg -f x11grab -video_size 1920x1080 -framerate 24 \ -i :0.0 -c:v libx264 -preset slow -crf 28 output.mp4-crf 28是控制质量的数值,范围 0-51,越小质量越高、文件越大,常用范围是 18-28。桌面录屏用 28 通常肉眼看不出明显差别,但文件能小一半。加上-preset slow编码更仔细,文件更小,代价是录制时 CPU 占用更高,适合录制完事后处理的场景,现场实时录制用ultrafast就好。
5.2 录屏没有声音
这个问题多半出在音频输入源没配对。Linux 下常见音频接口是 ALSA 和 PulseAudio。ffmpeg录屏默认不会自动选音频输入,你得手动指定。先用:
pactl list sources查一下有效的音频源设备名,然后录屏时带上:
ffmpeg -f x11grab ... -f pulse -i alsa_input.usb-device.mono-fallback ...另外一个常见误区:录屏时 OBS 或者 ffmpeg 显示有声音,播放器里没声音。这通常是播放器解码或声道映射问题,用 VLC 或系统自带播放器打开,检查音频轨是否被静音,基本能解决。
如果只是录自己说话声,建议先单独用arecord测一下麦克风通不通:
arecord -d 5 test.wav aplay test.wav能听到回声说明麦克风没问题,问题就出在录制软件的音频源选择上。
5.3 日志文件权限不够
用script -a或重定向保存日志时,有时候会碰到Permission denied,尤其是往/var/log这类系统目录里写。最直接的解法是加sudo,但这样会导致日志文件属主是 root,后续普通用户去读或者轮转可能会报错。建议的路径是:
- 个人工作环境:日志统一写到用户目录下,比如
~/logs/,避免权限问题。 - 服务环境:给运行服务的用户单独建日志目录,用
chown归属到该用户,而不是一律用 root 跑服务。
比如:
sudo mkdir -p /var/log/myapp sudo chown myuser:myuser /var/log/myapp sudo chmod 755 /var/log/myapp这样后续服务往里面写日志就不会再遇到权限拒绝,同时 logrotate 配置也不需要额外的 sudo 通知。很多人上来就给整个目录chmod 777,能用但隐患极大——任何用户都能删改日志,严重时连日志本身都可能被恶意篡改,我不建议这么干。
5.4 磁盘空间被录屏和日志撑爆
录屏视频和日志文件都是磁盘消耗大户。尤其是录屏,幾十分钟的 1080p 视频可能就有 1-2 GB。我在实践中总结了三个习惯:
- 录完立刻看文件大小,不再需要的马上删除。
- 定期用
du -sh ~/screen_logs/*统计,清理超过一周的旧录屏。 - 日志目录用 logrotate 做轮转,并按天压缩。
另外,如果录屏只是临时需求,可以录制结束后马上转换格式再删原文件。比如无损录制的.mkv转成mp4压缩后,体积能缩到原来的三分之一到一半,再删掉 mkv 原始文件。整个过程几分钟,但能省好几个 GB。
5.5 script 录制文件看起来乱码
如果你用script录过交互界面,再直接less或cat查看,经常是一堆^[[?25l、^M之类的控制字符。这是终端控制序列被一起录进去了,不是文件坏了。
想看干净内容,用以下方式之一:
col -b < session.log | less cat -v session.log | lesscol -b过滤掉大部分退格和控制字符,显示效果好很多。回放用scriptreplay时如果错位,先确认录制和回放的终端窗口大小一致。
另外还有一种情况,录制的文件里带有很多颜色转义码(\033[01;32m之类),这时候用sed简单过滤:
sed -r 's/\x1B\[[0-9;]*[mK]//g' session.log > clean.log这个正则能把 ANSI 颜色码清干净,处理完的日志特别适合直接贴到文档或者发送给同事。
5.6 录屏时鼠标光标不见了
OBS 或者ffmpeg录屏时,偶尔鼠标光标没有被录制进去。这个问题有三个常见原因:
- x11grab 默认不抓取光标,需要在
ffmpeg命令里加-cursor参数(有的版本叫-x11grab_cursor)。不过实测下来,这个参数的支持情况跟 X11 扩展有关,不一定在所有环境都生效。 - OBS 在“显示器采集”的属性里有“捕获光标”的选项,检查是否勾选。
- 桌面环境开了硬件光标,某些录制工具对硬件光标支持不佳,录出来的画面里光标直接消失。可以尝试在桌面设置里关闭“硬件光标加速”,或者改用软件渲染光标。
我自己碰到的多数是第三种情况,在虚拟机里尤其常见。收藏这几个排查方向,遇到时逐个试,基本都能解决。
6. 几条经验总结与实用建议
这里不再做那种官腔式总结,就说几个我长期实践下来最有价值的体会。
第一条,日志保存的习惯要像“条件反射”一样养成——只要开始一条可能产生大量输出或耗时较长的命令,立刻加上tee或重定向。不要等“这次可能很重要”再想起来,因为临时补录的效果远不如从一开始就录。我自己吃亏过多次,所以现在连apt install都会顺手加tee。
第二条,录制教学视频时,脚本化的ffmpeg命令比 GUI 工具更适合日常工作流。你可以把它写成一个函数放进~/.bashrc,以后随时调用:
function screencap() { local file="${1:-capture_$(date +%F_%H%M%S).mp4}" ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 \ -i :0.0 -c:v libx264 -crf 28 -preset ultrafast "$file" }终端里输入screencap就能录制,按q结束,录完自动生成带时间戳的文件名。配合screencap my_demo.mp4还能自定义文件名,非常灵活。
第三条,所有日志和录屏文件,要有一个固定的目录结构和命名习惯。我自己的目录如下:
~/records/ ├── logs/2024/01/15/ ├── video/2024/01/15_demo.mp4 └── archives/2023/12/有了这个习惯,找东西的效率高到飞起。别小看“文件管理”这种琐事,它在排查故障的时候帮了我不止一次大忙。
最后再说一个隐藏技巧:如果你在录屏的同时还要对终端操作截图,可以给gnome-screenshot配一个快捷键,随时截取当前屏幕。录屏视频 + 截图 + 文本日志三者组合,基本覆盖了所有“事后回溯”的场景,比单一手段安全得多。
希望这套日志保存和屏幕录制的组合方法能帮你少走弯路。这类“小工具,大用途”的东西,真正用起来之后,工作量能轻很多。