script 命令可完整捕获终端会话字节流,包括命令、输出、错误及控制字符;用 script -q -c "cmd" logfile 静默记录,或直接 script logfile 交互式记录,但不可嵌套使用。

用 script 命令完整捕获终端会话
当需要完整记录某次 Shell 操作(含命令输入、输出、错误、甚至控制字符),script 是最直接可靠的方案。它不依赖应用层日志,而是从伪终端层面抓取所有字节流。
- 运行
script -q -c "your_command" /path/to/logfile可静默执行并保存全过程;-q抑制启动/退出提示,适合脚本调用 - 交互式使用时,直接运行
script session.log,之后所有操作都会写入,输入exit或Ctrl+D结束记录 - 注意:默认记录中包含 ANSI 转义序列(如颜色、光标移动),用
script -e -c ...可启用“回放模式”兼容性,但更推荐后续用cat -v session.log或less -r查看 - 常见坑:
script无法嵌套使用——已在script会话中再执行script会失败并报错Script is already running
用 set -x + exec 记录命令执行轨迹
适用于调试 Shell 脚本本身逻辑,或需追溯某段自动化流程中实际执行了哪些命令及其参数展开结果。
- 在脚本开头加
set -x,所有后续命令会在执行前打印到stderr;配合exec 2> /path/to/trace.log可重定向该输出 - 若只希望部分代码块开启追踪,用
set -x和set +x包裹即可,避免全量日志干扰 - 注意变量未引号包裹导致的 word splitting 会在
set -x输出中暴露真实参数切分,这是调试优势,但也意味着敏感值(如密码)可能泄露——切勿在生产环境无脱敏启用 -
set -x不记录命令返回码或 stdout 内容,仅记录“将要执行什么”,和script的定位完全不同
用 logger 向系统日志写入结构化条目
当操作需纳入系统级审计体系(如 rsyslog 或 journald),应使用 logger,而非简单重定向到文件。
- 基础用法:
logger -t "mydeploy" "Starting rollback step 3",-t指定 tag,便于后续journalctl -t mydeploy过滤 - 配合
systemd服务时,可加--priority user.info或--id=$$(记录当前 PID),提升可关联性 - 注意:默认
logger发送至syslog,若系统使用systemd-journald,日志自动入库,但传统/var/log/messages可能不出现——验证请用journalctl -n 20 - 不要用
logger记录大量二进制输出或长文本,它设计用于短消息;超长内容会被截断(通常 1024 字符内较安全)
日志路径与权限管理的关键细节
无论用哪种方式记录,输出目标若为文件,权限和归属极易出问题,尤其涉及 sudo 或服务账户时。
- 避免
sudo script -c "cmd" /var/log/myrun.log—— 这会导致日志文件属主为root,普通用户后续无法追加或读取;正确做法是先创建文件并设好权限:sudo touch /var/log/myrun.log && sudo chmod 644 /var/log/myrun.log && sudo chown deploy:adm /var/log/myrun.log
- 用
exec >> /path/to/log 2>&1追加时,确保父 Shell 进程有写权限;若日志路径在/tmp,注意某些系统启用private tmp(如 systemd service),此时/tmp实际是隔离挂载,外部不可见 - 定期轮转不能只靠
logrotate配置,还要确认被记录进程是否支持SIGHUP重新打开文件(script和纯重定向都不支持),否则轮转后新日志仍写入旧 inode
script 日志里的时间来自终端模拟器,set -x 输出无时间,logger 虽带系统时间但可能跨时区。真要对齐多个来源的日志,得统一用 date +"%Y-%m-%d %H:%M:%S.%3N" 手动插桩,或者改用 ts(from moreutils)实时加戳。










