如何操作由"script"命令创建的时间和TypeScript文件?

3
作为调试过程中的重要一步,仔细查看时间和进展是必不可少的。经常使用 scriptscriptreplay,我想知道是否存在用于操作结果文件的工具。
示例(来自如何分析缓慢启动的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 2019 和 Script 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

在定时文件中的第12行(head -n 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

我的请求:
寻找更轻量级的东西...
这可能是一些小脚本片段,使用来现代化我的代码。
甚至可以是动态的!我可以想象一个使用NCurses的工具,带有进度条、显示和键盘控制,就像一种视频查看器: 开始停止下一步,...

很遗憾,在Stack Overflow上明确禁止询问工具推荐。请查看我应该避免询问哪些主题 - undefined
@tripleee,我同意这个原则,然而,我并不是在询问主观性问题,即从多个选择中进行选择,而是在寻找一种进行规律精确工作的方法。 - undefined
如果你想要进行精确的测量,那么秒钟就太长了,你应该使用微秒。否则,你需要执行一个任务,比如说重复1000次来计算平均时间。 - undefined
1
@David 你在我的帖子中哪里看到了“秒”这个词?如果你尝试使用scriptscriptreplay,计时文件是以微秒为单位的。使用[tag:bash]。变量$EPOCHREALTIME显示的时间是以纳秒为单位的... 是的,我经常使用time for i in {1..100000};do someCommandToTest;done之类的语句... - undefined
哦,抱歉 @F.Hauri,我在 ls -a 的输出中看到了时间,不知怎么把它误认为你正在测量的时间。 - undefined
显示剩余2条评论
1个回答

2

这是第一次尝试,基于

这个使用 (require) xterm 并在一个新的终端中运行重演脚本输出,并且与脚本运行时具有相同的大小。交互非常简洁。

这里有两个选项:

  • -t 通过使用 内置 read 来进行时间间隔,所以可以通过按下 Return 来加速。
  • -w 提交要搜索的单词或字符串。进度将停止,直到您按下 Return
#!/bin/bash
export LANG=C LANGUAGE=C
die() { echo >&2 "$0 ERR: $@";exit 1;}
doTime=false
while getopts "tw:" opt;do case $opt in
                       t ) doTime=true;;
                       w ) searchFor=${OPTARG};;
                   esac;done
shift $((OPTIND-1))

exec {log}<"$1" || die "Can't open logfile '$1'."
exec {tim}<"$2" || die "Can't open timing file '$2'-"
IFS='' read -ru $log line || die "error reading logfile."
sTerm=${line#*TERM=\"} sTerm=${sTerm%%\"*}
sCols=${line#*COLUMNS=\"} sCols=${sCols%%\"*}
sLnes=${line#*LINES=\"} sLnes=${sLnes%%\"*}
[ "$sTerm" ] || die "No TERM var found."
((sCols * sLnes)) || die "No valid size"

exec {term}<> >(:)
xterm -fs 11 -geom ${sCols}x$sLnes -T ScripReplay -S00/$term &
XTPid=$!
read -u $term -t 1 XTWinId

declare -i TTime=0   TChar=0
while read -u $tim time chars;do
    IFS='' read -d '' -rn $chars -u $log str
    printf >&$term '%s' "$str"
    TTime+=10#${time/.}    TChar+=chars
    ttm=00000$TTime
    printf "\rCrt %12.6f, %3d chars - Tot:  %12.6f %11d\n" $time $chars \
           ${ttm::-6}.${ttm: -6} $TChar
    [ "$searchFor" ] &&
        case $str in *$searchFor* ) read -p "Found: '$searchFor'. " _;;esac
    $doTime && read -t $time _
done

exec {tim}<&-
exec {log}<&-
read -pDone.\  _
exec {term}>&-
kill $XTPid

希望在中也有相同的功能!

更多特色版本请访问我的网站:

这里:scriptReplay.sh.txt, scriptReplay.sh

Script Replay based debugging tool

Command line optional arguments:
  -h         Show this.
  -t         Reproduce delays between outputs ('$doTime', default false)
  -d DIVISOR Integer divisor of delay [-t] ('$divisor', default 10)
  -w STRING  Stop output when STRING found, wait for user interaction
  -n         Don't wait when STRING found

Interactive interface: Once run, ${0##*/} will open another xterm
window to show console dialog as recorded by script.
While running, interaction in first console could be:
  [t]       Toggle reproducing time delays between outputs
  [d]       Enter a new INTEGER for divisor
  [s]       Enter a new STRING to search for
  [q]       Quit.

又一个 脚本

这里提供一个小而快速的解决方案(使用 bc):

#!/bin/bash

coproc exec bc
echo >&${COPROC[1]} t=0.0
{
    declare -i Tlen=0
    read -u $lg hl
    echo HEAD $hl
    while read -u $tm tim chrs ;do
        echo "t+=$tim;t" >&${COPROC[1]}
        read -u ${COPROC[0]} Ttim
        Tlen+=$chrs
        LANG=C IFS='' read -d '' -u $lg -rn $chrs str
        printf '%10.6f %-4d|%12.6f %12d: %s\n' $tim $chrs $Ttim $Tlen "${str@Q}"
    done
    while read -u $lg str ;do
        echo "TAIL: ${str@Q}"
    done
} {lg}<"$1" {tm}<"$2"

运行此帖子中第一个命令生成的 script.logscript.tim 将在我的树莓派上呈现:

$ ./quickReplay.sh script.{log,tim}
HEAD Script started on 2022-04-07 14:37:19+02:00 [TERM="xterm" TTY="/dev/pts/0" COLUMNS="80" LINES="24"]
  0.083946 11  |    0.083946           11: '+ (( i=3 ))'
  0.001231 2   |    0.085177           13: $'\r\n'
  0.001951 11  |    0.087128           24: '+ (( i-- ))'
  0.001023 2   |    0.088151           26: $'\r\n'
  0.001947 10  |    0.090098           36: '+ sleep .1'
  0.001412 2   |    0.091510           38: $'\r\n'
  0.123944 9   |    0.215454           47: '+ (( 1 ))'
  0.005763 2   |    0.221217           49: $'\r\n'
  0.001559 11  |    0.222776           60: '+ (( i-- ))'
  0.001027 2   |    0.223803           62: $'\r\n'
  0.001908 10  |    0.225711           72: '+ sleep .1'
  0.001256 2   |    0.226967           74: $'\r\n'
  0.126024 9   |    0.352991           83: '+ (( 1 ))'
  0.001316 2   |    0.354307           85: $'\r\n'
  0.001804 11  |    0.356111           96: '+ (( i-- ))'
  0.001076 2   |    0.357187           98: $'\r\n'
  0.002086 10  |    0.359273          108: '+ sleep .1'
  0.002059 2   |    0.361332          110: $'\r\n'
  0.125725 9   |    0.487057          119: '+ (( 1 ))'
  0.001147 2   |    0.488204          121: $'\r\n'
  0.001768 11  |    0.489972          132: '+ (( i-- ))'
  0.001346 2   |    0.491318          134: $'\r\n'
  0.002247 11  |    0.493565          145: '+ (( i=2 ))'
  0.007743 2   |    0.501308          147: $'\r\n'
  0.001628 11  |    0.502936          158: '+ (( i-- ))'
  0.000259 2   |    0.503195          160: $'\r\n'
  0.000810 32  |    0.504005          192: '+ tar -cf /tmp/test.tar -C / bin'
  0.001128 2   |    0.505133          194: $'\r\n'
  1.336998 20  |    1.842131          214: '+ gzip /tmp/test.tar'
  0.001093 2   |    1.843224          216: $'\r\n'
 34.593442 23  |   36.436666          239: $'+ rm /tmp/test.tar.gz\r\n'
  0.041637 9   |   36.478303          248: '+ (( 1 ))'
  0.001435 2   |   36.479738          250: $'\r\n'
  0.001617 11  |   36.481355          261: '+ (( i-- ))'
  0.010704 2   |   36.492059          263: $'\r\n'
  0.001931 32  |   36.493990          295: '+ tar -cf /tmp/test.tar -C / bin'
  0.001085 2   |   36.495075          297: $'\r\n'
  0.737705 20  |   37.232780          317: '+ gzip /tmp/test.tar'
  0.001179 2   |   37.233959          319: $'\r\n'
 35.705253 21  |   72.939212          340: '+ rm /tmp/test.tar.gz'
  0.001160 2   |   72.940372          342: $'\r\n'
  0.053247 9   |   72.993619          351: '+ (( 1 ))'
  0.001170 2   |   72.994789          353: $'\r\n'
  0.002150 11  |   72.996939          364: '+ (( i-- ))'
  0.001353 2   |   72.998292          366: $'\r\n'
TAIL: ''
TAIL: 'Script done on 2022-04-07 14:38:32+02:00 [COMMAND_EXIT_CODE="0"]'

最后那个 quickReplay.sh 脚本非常好用,正是我一直在寻找的。谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接