小能豆

如何操作“script”命令创建的计时和打字文件?

py

作为调试过程的重要步骤,仔细查找时间和进程是必须的

script经常使用scriptreplay,我想知道是否存在用于操作结果文件的工具。

示例(来自如何分析 bash shell 脚本启动缓慢?):

script -t script.log 2>script.tim -c 'bash -x -c "
    for ((i=3;i--;));do sleep .1;done

    for ((i=2;i--;)) ;do
        tar -cf /tmp/test.tar -C / bin
        gzip /tmp/test.tar
        rm /tmp/test.tar.gz
    done
"'

然后有两个文件:

-rw-r--r-- 1 user  user  472 Sep 25 10:44 script.log
-rw-r--r-- 1 user  user  213 Sep 25 10:44 script.tim

我可以通过以下方式重演该脚本:

scriptreplay --timing script.tim --typescript script.log 10

作为执行时间除数,10使重放速度提高 10 倍,或者

scriptreplay --timing script.tim --typescript script.log .1

使重播速度变慢 10 倍。

我想知道是否存在类似的工具:

好吧,从那里开始:

cut -d \  -f1 <script.tim | xargs  | tr \  + | bc
3.616809

输出总体执行时间,或者如果有太多行:

cut -d \  -f1 <script.tim | xargs  | tr \  + | bc | xargs  | tr \  + | bc
3.616809

cut -d \  -f2 <script.tim | xargs  | tr \  + | bc
366
sed '1d;$d' script.log |wc -c
367

检查整体脚本输出大小。(sed删除日志的第一行和最后一行,其中包含:Script started on Wed Sep 25 14:40:20 2019Script done on Wed Sep 25 14:40:23 2019。)

然后,计算某个时间的日志大小(指针)

perl -e 'my ($l,$t,$p)=(0,0,0); # line totTime pos
    open FH,"<".$ARGV[0] || die;
    while (<FH>) {
        my ($d,$n)=split" "; # duration numBytes
        $l++;
        $t+=$d;
        $p+=$n;
        $t>=${ARGV[1]} && do {
            print $l." ".$p."\n";
            exit 0;
        };
    };' script.tim  1.2
12 216

TimingFile( head -n 12) 中的第 12 行和 TypeScript 文件 () 中的字节位置 216 head -c 216

或者如果我正在搜索*某个字符串的*运行时间:

grep -ob 'tar.*test' script.log 
217:tar -cf /tmp/test
320:tar -cf /tmp/test

perl -e 'my ($l,$t,$p)=(0,0,0);open FH,"<".$ARGV[0] || die;while (<FH>) { 
    my ($d,$n)=split" ";$l++;$t+=$d;$p+=$n;$p>=${ARGV[1]} && do {
      print $l." ".$p."\n";exit 0;};};' script.tim  217
17 228

head -n 17 script.tim | cut -d \  -f1 | xargs | tr \  + | bc
1.091276

我的请求:

寻找更轻松的东西…

  • 这可能是一些小脚本,使用Python为了使我的perl。
  • 甚至是动态的!我可以想象一个使用 NCurses 的工具,带有进度条、一些显示和一些键盘控制,就像一种视频查看器:Start,,,Stop…Next step

阅读 21

收藏
2024-11-04

共1个答案

小能豆

使用 Python 来简化你的分析可以更轻松地操作 script.logscript.tim 文件。我们可以编写一个 Python 脚本来动态显示重播过程的执行时间和日志大小,甚至可以添加键盘控制来暂停和跳过步骤。下面是一个可以帮助你执行这些任务的基本脚本。对于更复杂的交互式界面(如 Ncurses),也可以扩展。

基本 Python 分析脚本

import time
import sys

def parse_timing_file(timing_file):
    with open(timing_file, 'r') as f:
        timings = []
        for line in f:
            duration, bytes_count = line.split()
            timings.append((float(duration), int(bytes_count)))
    return timings

def parse_log_file(log_file):
    with open(log_file, 'r') as f:
        log = f.read()
    return log

def replay_script(timing_file, log_file, speed_factor=1.0):
    timings = parse_timing_file(timing_file)
    log = parse_log_file(log_file)

    pointer = 0  # Log file pointer
    start_time = time.time()

    for duration, byte_count in timings:
        # Adjust duration according to speed factor
        time.sleep(duration / speed_factor)

        # Print log output up to the current byte position
        sys.stdout.write(log[pointer:pointer + byte_count])
        sys.stdout.flush()

        # Update pointer to the new position
        pointer += byte_count

    print(f"\nReplay finished in {time.time() - start_time:.2f} seconds (speed factor: {speed_factor})")

# Example usage
timing_file = "script.tim"
log_file = "script.log"
speed_factor = 10  # Adjust speed as needed

replay_script(timing_file, log_file, speed_factor)

功能说明

  1. 解析parse_timing_fileparse_log_file 分别解析 script.timscript.log 文件。
  2. 回放replay_script 函数逐步执行每个时间和字节计数,使用 sys.stdout.write 模拟回放并根据 speed_factor 调整播放速度。
  3. 控制:调整 speed_factor 值可以改变播放速度,例如,10 会加快速度,0.1 会减慢速度。

扩展功能

可以考虑使用 curses 模块来实现更交互式的界面,如暂停和快进控制。以下是如何在 Python 中引入基本交互控制的示例:

import curses
import time

def interactive_replay(timing_file, log_file, speed_factor=1.0):
    timings = parse_timing_file(timing_file)
    log = parse_log_file(log_file)

    def main(stdscr):
        pointer = 0
        pause = False
        replay_speed = speed_factor

        stdscr.nodelay(1)  # Non-blocking input
        stdscr.clear()
        stdscr.addstr(0, 0, "Press 'p' to pause/play, 'q' to quit, '+' to speed up, '-' to slow down")

        for duration, byte_count in timings:
            # Handle keyboard input
            key = stdscr.getch()
            if key == ord('q'):
                break  # Quit the replay
            elif key == ord('p'):
                pause = not pause  # Toggle pause
            elif key == ord('+'):
                replay_speed *= 1.5  # Speed up
            elif key == ord('-'):
                replay_speed /= 1.5  # Slow down

            if pause:
                time.sleep(0.1)
                continue

            # Adjust timing according to replay speed
            time.sleep(duration / replay_speed)

            # Print log content
            stdscr.addstr(1, 0, log[pointer:pointer + byte_count])
            stdscr.clrtoeol()
            stdscr.refresh()

            pointer += byte_count

    curses.wrapper(main)

# Run the interactive replay
interactive_replay(timing_file, log_file, speed_factor)

扩展功能说明

  1. 交互式回放:使用 curses 库来管理键盘控制和显示内容。
  2. 控制命令:通过以下命令控制脚本:
  3. 'p':暂停/播放
  4. 'q':退出
  5. '+''-':加快或减慢回放速度

进一步改进

可以进一步扩展脚本,使其具有更多的功能,例如:
- 跳到特定时间:允许用户输入时间戳并直接跳转到对应的输出位置。
- 查找功能:实现搜索功能以在回放中找到特定文本或模式。
- 进度条:显示整个回放过程的进度条或剩余时间。

2024-11-04