如何计算 bash 别名执行所需的时间(已解决...也许?)

问题描述 投票:0回答:1

我的 Dreadnaught 嵌入式 Linux 系统上有一些别名,其中一些有相当长的工作列表需要完成。我正在尝试提高这些任务的效率,并尝试计算每个排列花费的时间,以便我可以确认哪个是最快的排列。

我已经将我的脚本分成几个部分,并发现每个部分都有效......但当它们放在一起时却不起作用。我会将尝试放在问题的末尾,这样它们就不会淹没问题......

但是,经过几个小时试图弄清楚为什么它似乎部分工作而不是整体工作后,我发现命令替换是在定义别名时评估的,而不是在执行别名时评估的。

如何创建一个为多个任务自动计时的别名(调用其他别名、调用系统)。

我尝试使用函数来代替;同样不成功。

我尝试过

time
,但它不喜欢将别名传递给它;而且我的别名“调用了许多其他别名”和系统调用,因此解压它们是不切实际的。

有没有办法创建 bash 别名(或可以从 bash 调用的其他方法?)来对自身和/或其他进程进行计时?

更新 - 可能的解决方案,但正在寻找更好的建议?

正如我经常发现的那样,写出一个关于 SO 的问题会让我仔细地解释它,这在某种程度上触发了我的头脑去思考我以前没有想到过的替代方案。我刚刚编写了一个调用任务的 bash 脚本 - 因为它没有使用“别名”来记录时间,而是直接调用时间函数:

#!/bin/bash

echo "== Task 1 Start =="
timerstart1=$(eval 'date +%s')
TimerStartstr1=$(eval 'date -d@$((timerstart1))')
echo "Task 1 started at   $timerstart1 = $TimerStartstr1"

myTask1

timerend1=$(eval 'date +%s')
TimerEndstr1=$(eval 'date -d@$timerend1')
echo "Task 1 completed at $timerend1 = $TimerEndstr1"
duration1=$(($timerend1 - $timerstart1))
echo "=========== Task 1 Complete, took $duration1 =================="


echo "== Task 2 Start =="
timerstart2=$(eval 'date +%s')
TimerStartstr2=$(eval 'date -d@$((timerstart2))')
echo "Task 2 started at   $timerstart2 = $TimerStartstr2"

MyTask2

timerend2=$(eval 'date +%s')
TimerEndstr2=$(eval 'date -d@$timerend2')
echo "Task 2 completed at $timerend2 = $TimerEndstr2"
duration2=$(($timerend2 - $timerstart2))
echo "=========== Task 2 Complete, took $duration2 =================="

echo "Speed improvement = $(($duration1 - $duration2))"

而且,幸灾乐祸的是:我的“改进的”Task2 实际上比原来花费的时间更长 - 83 秒 vs 70 秒!

以下是工作的构建(大部分)似乎可以独立工作:

[user@Dreadnaught log]$ echo ==Start==; timerstart=$(eval 'date +%s'); TimerStartstr=$(eval 'date -d@$((timerstart))'); echo Started at \ \ $timerstart = $TimerStartstr;
==Start==
Started at   1710780061 = Mon Mar 18 16:41:01 GMT 2024
[user@Dreadnaught log]$ timerend=$(eval 'date +%s'); TimerEndstr=$(eval 'date -d@$timerend'); echo Completed at $timerend = $TimerEndstr;
Completed at 1710780075 = Mon Mar 18 16:41:15 GMT 2024
[user@Dreadnaught log]$ echo =========== TestTimerTask Complete, took $(($timerend - $timerstart)) ==================
=========== TestTimerTask Complete, took 14 ==================
[user@Dreadnaught log]$ alias timertest="echo ==Start==; timerstart=$(eval 'date +%s'); TimerStartstr=$(eval 'date -d@$((timerstart))'); echo Started at \ \ $timerstart = $TimerStartstr; read -p 'Waiting for input' >/dev/tty; timerend=$(eval 'date +%s'); TimerEndstr=$(eval 'date -d@$timerend'); echo Completed at $timerend = $TimerEndstr; echo =========== TestTimerTask Complete, took $(($timerend - $timerstart)) =================="
[user@Dreadnaught log]$ timertest
==Start==
-ash: Mar: not found
Started at   1710780061 = Mon Mar 18 16:41:01 GMT 2024
Waiting for input
-ash: Mar: not found
Completed at 1710780075 = Mon Mar 18 16:41:15 GMT 2024
=========== TestTimerTask Complete, took 14 ==================
[user@Dreadnaught log]$ timertest
==Start==
-ash: Mar: not found
Started at   1710780061 = Mon Mar 18 16:41:01 GMT 2024
Waiting for input
-ash: Mar: not found
Completed at 1710780075 = Mon Mar 18 16:41:15 GMT 2024
=========== TestTimerTask Complete, took 14 ==================
[user@Dreadnaught log]$ alias timertest="echo ==Start==; timerstart=$(eval 'date +%s'); TimerStartstr=$(eval 'date -d@$((timerstart))'); echo Started at \ \ $timerstart = $TimerStartstr; sleep 2; timerend=$(eval 'date +%s'); TimerEndstr=$(eval 'date -d@$timerend'); echo Completed at $timerend = $TimerEndstr; echo =========== TestTimerTask Complete, took $(($timerend - $timerstart)) =================="
[user@Dreadnaught log]$ timertest
==Start==
-ash: Mar: not found
Started at   1710780100 = Mon Mar 18 16:41:01 GMT 2024
-ash: Mar: not found
Completed at 1710780101 = Mon Mar 18 16:41:15 GMT 2024
=========== TestTimerTask Complete, took 1 ==================
[user@Dreadnaught log]$


[user@Dreadnaught log]$ alias timerstart="f(){ timerstart=$(eval 'date +%s'); TimerStartstr=$(eval 'date -d@$((timerstart))'); echo Started at \ \ $timerstart = $TimerStartstr; unset -f f; };f"
[user@Dreadnaught log]$ alias timerend="f(){ timerend=$(eval 'date +%s'); TimerEndstr=$(eval 'date -d@$((timerend))'); echo Finished at \ \ $timerend = $TimerEndstr; unset -f f; };f; echo =========== TestTimerTask Complete, took $(($timerend - $timerstart)) =================="
[user@Dreadnaught log]$ alias timertest="timerstart; read -p 'Waiting for input' >/dev/tty; timerend"
[user@Dreadnaught log]$ timertest
-ash: Mar: not found
Started at   1710780677 = Mon Mar 18 16:41:01 GMT 2024
Waiting for input
-ash: Mar: not found
Finished at   1710780677 = Mon Mar 18 16:41:15 GMT 2024
=========== TestTimerTask Complete, took 0 ==================
[user@Dreadnaught log]$
bash timer alias
1个回答
0
投票

听起来您在应该使用函数时使用了别名,并且存在一些其他问题,例如无缘无故地调用

eval
。我认为这就是你想要做的:

$ cat tst.sh
#!/usr/bin/env bash

myTask1() { sleep 3; }
myTask2() { sleep 5; }

getsecs() {
    local secs msg="$1"

    printf -v secs '%(%s)T'
    printf '%s at  %d = %(%Y-%m-%d %H:%M:%S)T\n' "$msg" "$secs" >&2

    echo "$secs"
}

timertest() {
    local begSecs endSecs

    begSecs=$(getsecs "$* Started")

    "$@"

    endSecs=$(getsecs "$* Finished")

    printf '=========== %s Complete, took %d ==================\n' "$*" "$(( endSecs - begSecs ))" >&2
}

timertest myTask1

timertest myTask2

$ ./tst.sh
myTask1 Started at  1710786953 = 2024-03-18 13:35:53
myTask1 Finished at  1710786956 = 2024-03-18 13:35:56
=========== myTask1 Complete, took 3 ==================
myTask2 Started at  1710786956 = 2024-03-18 13:35:56
myTask2 Finished at  1710786962 = 2024-03-18 13:36:02
=========== myTask2 Complete, took 6 ==================
© www.soinside.com 2019 - 2024. All rights reserved.