SSH会话记录添加客户端时间戳失败,求有效实现方案
问题
原本使用以下命令通过SSH登录主机并将会话记录到txt文件:
ssh -t dobby1997@${IP} "script -t 2> timing.log" | tee "ssh_session.txt"
现在需要为txt文件的每行添加客户端的epoch时间戳(而非主机时间戳),尝试用awk处理的命令如下:
ssh -t dobby1997@${IP} "script -t 2> timing.log" | awk -v epoch="$(date +%s)" '{print epoch, $0 }' | tee "ssh_session.txt"
但输入密码登录后无任何反应,期望实现的输出格式如下:
1686322204 dobby@ubuntu:~/matrix_math_timer$ make 1686322205 gcc -c main.c 1686322206 gcc main.o matrix_impl.o -o matrix_math_timer 1686322207 dobby@ubuntu:~/matrix_math_timer$ ./cache_money 1686322208 Time taken: 0.189859 1686322208 Time taken: 0.152965 1686322214 Time taken: 6.197541 1686322218 Time taken: 4.893529 1686322220 dobby@ubuntu:~/matrix_math_timer$ make clean 1686322220 rm *.o matrix_math_timer 1686322220 dobby@ubuntu:~/matrix_math_timer$
问题根源
- awk缓冲机制:默认情况下awk会缓冲输出,不会实时打印内容,导致会话无反馈。
- 时间戳初始化单一:
-v epoch="$(date +%s)"仅在awk启动时获取一次时间,所有行都会复用该值,无法实现每行实时时间戳。 - 终端交互冲突:
ssh -t分配的伪终端与管道后的awk处理相互干扰,导致登录后无响应。
修正方案
方案1:基于awk的实时处理
用stdbuf关闭awk的输出缓冲,同时在awk内部实时获取客户端时间戳:
ssh -t dobby1997@${IP} "script -q -c '\$SHELL' /dev/null" | stdbuf -oL awk '{cmd="date +%s"; cmd | getline epoch; close(cmd); print epoch, $0}' | tee ssh_session.txt
- 细节说明:
script -q -c '\$SHELL' /dev/null:-q启用静默模式,-c指定执行远程shell,/dev/null避免远程生成日志文件,仅将会话内容输出到stdout。stdbuf -oL:强制awk采用行缓冲模式,确保内容实时输出。cmd="date +%s"; cmd | getline epoch; close(cmd):每次处理行时都重新获取客户端当前时间戳,避免重复使用初始值。
方案2:用ts命令简化实现(需安装moreutils包)
如果系统安装了moreutils工具包,可直接用ts命令实现:
ssh -t dobby1997@${IP} "script -q -c '\$SHELL' /dev/null" | ts '%s' | tee ssh_session.txt
ts '%s':自动为每行添加客户端的epoch时间戳,自带行缓冲,实时输出。
额外注意事项
- 若需保留远程的
timing.log,可将script命令调整为:script -t 2> timing.log -q -c '\$SHELL' - 避免直接让
ssh -t的终端输出直接进入管道,通过script在远程处理终端会话后再输出到管道,可避免交互冲突。
内容的提问来源于stack exchange,提问作者DobbyFenk
相关产品推荐
相关产品推荐

