【问题标题】:Bash shell script for 100 iterations and log time taken用于 100 次迭代和记录时间的 Bash shell 脚本
【发布时间】:2011-04-13 00:51:20
【问题描述】:

如何使用 bash shell 脚本运行 100 次迭代?我想知道执行一个命令需要多长时间(开始和结束时间)。我想跟踪当前正在运行的迭代。我想记录每次迭代。我有一个需要运行和记录的自动化脚本。

for i in 1 2 3
do
    command1
done

但我想知道完成一次迭代需要多长时间 - 并将信息也写入日志文件!

【问题讨论】:

标签: bash


【解决方案1】:

此脚本基于the answer from @marian0,但运行时间没有限制。将其命名为timeit.sh,然后执行./timeit.sh 10 ./script 以运行./script 10 次并打印平均时间。可以根据需要添加其他参数。

#!/bin/bash

for i in `seq 1 $1`; do
    time "${@:2}"
done 2>&1 |\
    grep ^real |\
    sed -r -e "s/.*real\t([[:digit:]]+)m([[:digit:]]+\.[[:digit:]]+)s/\1 \2/" |\
    awk '{sum += $1 * 60 + $2} END {print sum / NR}'

【讨论】:

    【解决方案2】:

    您也可以在迭代中使用seq

    for i in `seq 1 100`; do ... done
    

    【讨论】:

    • $(seq 1 100) 和 {1..100} 不一样吗?
    【解决方案3】:

    你可以试试:

    for i in {1..100}; do time some_script.sh; done 2>&1 | grep ^real | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'
    

    说明

    • for 循环运行 some_script.sh 100 次,用time 测量其执行时间
    • for循环的stderr被重定向到stdout,这是为了捕获time的输出,这样我们就可以grep了
    • grep ^real 是在time 的输出中只获取以“real”开头的行
    • sed 是删除行首至分钟部分(在time 的输出中)
    • 对于每一行,awk 加到总和上,这样最后就可以输出平均值,即总和除以输入记录数(= NR

    限制

    sn -p 假设 some_script.sh 的运行时间小于 1 分钟,否则根本不起作用。根据您的系统,time 内置可能会有所不同。另一种选择是使用时间命令 /usr/bin/time 而不是 bash 内置。

    注意:此脚本提取自here

    【讨论】:

    • 我想给组合实验计时,说运行some_script.sh 10次时的总运行时间。不确定是否属实,但如果我按照你的方式做,我会执行 10 次不准确的 time 实验,因为 some_script.sh 每次都完成得太快。
    • 这部分:awk '{sum += $1} END {print sum / NR}'所有运行的总时间相加,然后除以执行次数。所以它计算所有运行的平均值。
    【解决方案4】:

    以下脚本显示了一种方法。

    #!/usr/bin/bash
    for i in {1..100} ; do
        echo =============================
        echo "Number $i: $(date +%Y-%m-%d-%H:%M:%S)"
        ( time ( echo $i ; sleep 1 ) ) 2>&1 | sed 's/^/   /'
    done | tee timing.log
    

    它使用bash 范围功能运行循环的 100 次迭代,输出循环计数器和日期。

    然后它会为您的命令计时(在这种情况下为echo $i ; sleep 1)并结合标准输出和错误,然后对其进行很好的格式化,并将其发送到终端和日志文件以供以后分析。

    五次迭代的小样运行:

    pax> testprog.sh
    =============================
    Number 1: 2010-09-16-13:44:19
       1
       real 0m1.063s
       user 0m0.077s
       sys  0m0.015s
    =============================
    Number 2: 2010-09-16-13:44:20
       2
       real 0m1.056s
       user 0m0.030s
       sys  0m0.046s
    =============================
    Number 3: 2010-09-16-13:44:21
       3
       real 0m1.057s
       user 0m0.046s
       sys  0m0.030s
    =============================
    Number 4: 2010-09-16-13:44:22
       4
       real 0m1.057s
       user 0m0.061s
       sys  0m0.031s
    =============================
    Number 5: 2010-09-16-13:44:23
       5
       real 0m1.057s
       user 0m0.046s
       sys  0m0.015s
    

    【讨论】:

      【解决方案5】:
      for ((i = 1; i <= 100; i++)); do
          echo "--- Iteration #$i: $(date) ---"
          time command1
      done 2>&1 | tee timing.log
      

      这里发生了很多事情。发生了什么事?

      1. for 循环使用 C 样式语法从 1 迭代到 100。
      2. echo 打印输出中的$i 打印当前迭代编号。
      3. $(date) 在每个打印输出中插入一个时间戳。
      4. time 命令运行命令并打印执行所需的时间。
      5. 循环内所有内容的输出都通过管道传输到tee,这会将副本保存到timing.log
      6. 2&gt;&amp;1 将 stderr 重定向到 stdout,以便日志文件包含常规输出和错误消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-15
        • 1970-01-01
        • 1970-01-01
        • 2012-11-25
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多